diff --git a/src/arch/x86/mod.rs b/src/arch/x86/mod.rs index 2366c6d..d17b2fa 100644 --- a/src/arch/x86/mod.rs +++ b/src/arch/x86/mod.rs @@ -1,48 +1,33 @@ // This file is part of libfringe, a low-level green threading library. // Copyright (c) edef // See the LICENSE file included in this distribution. -use void::Void; +pub use self::common::*; -use stack::Stack; -use super::common::{push, rust_trampoline}; - -pub const STACK_ALIGN: usize = 16; - -#[derive(Debug)] -pub struct Registers { - esp: *mut usize +macro_rules! init { + ($sp:expr, $f_ptr:expr, $tramp:expr) => { + asm!(include_str!("x86/init.s") + : "={eax}"($sp) + : "{eax}" ($sp), + "{ebx}" ($tramp), + "{ecx}" ($f_ptr) + : + : "volatile") + }; } -impl Registers { - #[inline] - pub unsafe fn new(stack: &mut S, f: F) -> Registers - where S: Stack, F: FnOnce() -> Void { - let mut sp = stack.top() as *mut usize; - let f_ptr = push(&mut sp, f); - - asm!(include_str!("init.s") - : "={eax}"(sp) - : "{eax}" (sp), - "{ebx}" (rust_trampoline:: as unsafe extern "C" fn(*const F) -> !), - "{ecx}" (f_ptr) - : - : "volatile"); - - Registers { esp: sp } - } - - #[inline(always)] - pub unsafe fn swap(out_regs: *mut Registers, in_regs: *const Registers) { - let out_espp = &mut (*out_regs).esp; - let in_espp = &(*in_regs).esp; - asm!(include_str!("swap.s") - : - : "{eax}" (out_espp), - "{ebx}" (in_espp) - : "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp", - "mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7", - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", - "cc" - : "volatile"); - } +macro_rules! swap { + ($out_spp:expr, $in_spp:expr) => { + asm!(include_str!("x86/swap.s") + : + : "{eax}" ($out_spp), + "{ebx}" ($in_spp) + : "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp", + "mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "cc" + : "volatile") + }; } + +#[path = "../x86_common.rs"] +mod common; diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index ff2ef03..3706383 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -1,50 +1,36 @@ // This file is part of libfringe, a low-level green threading library. // Copyright (c) edef // See the LICENSE file included in this distribution. -use stack::Stack; -use void::Void; -use super::common::{push, rust_trampoline}; +pub use self::common::*; -pub const STACK_ALIGN: usize = 16; - -#[derive(Debug)] -pub struct Registers { - rsp: *mut usize -} - -impl Registers { - #[inline] - pub unsafe fn new(stack: &mut S, f: F) -> Registers - where S: Stack, F: FnOnce() -> Void { - let mut sp = stack.top() as *mut usize; - let f_ptr = push(&mut sp, f); - - asm!(include_str!("init.s") - : "={rdi}"(sp) - : "{rdi}" (sp), - "{rsi}" (rust_trampoline:: as unsafe extern "C" fn(*const F) -> !), - "{rdx}" (f_ptr) - : - : "volatile"); - - Registers { rsp: sp } - } - - #[inline(always)] - pub unsafe fn swap(out_regs: *mut Registers, in_regs: *const Registers) { - let out_rspp = &mut (*out_regs).rsp; - let in_rspp = &(*in_regs).rsp; - asm!(include_str!("swap.s") - : - : "{rdi}" (out_rspp), - "{rsi}" (in_rspp) - : "rax", "rbx", "rcx", "rdx", "rsi", "rdi", //"rbp", "rsp", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", - "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", - "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31" - "cc" - : "volatile"); +macro_rules! init { + ($sp:expr, $f_ptr:expr, $tramp:expr) => { + asm!(include_str!("x86_64/init.s") + : "={rdi}"($sp) + : "{rdi}" ($sp), + "{rsi}" ($tramp), + "{rdx}" ($f_ptr) + : + : "volatile"); } } + +macro_rules! swap { + ($out_spp:expr, $in_spp:expr) => { + asm!(include_str!("x86_64/swap.s") + : + : "{rdi}" ($out_spp) + "{rsi}" ($in_spp) + : "rax", "rbx", "rcx", "rdx", "rsi", "rdi", //"rbp", "rsp", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", + "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", + "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31" + "cc" + : "volatile"); + } +} + +#[path = "../x86_common.rs"] +mod common; diff --git a/src/arch/x86_common.rs b/src/arch/x86_common.rs new file mode 100644 index 0000000..de1f6b5 --- /dev/null +++ b/src/arch/x86_common.rs @@ -0,0 +1,35 @@ +// This file is part of libfringe, a low-level green threading library. +// Copyright (c) 2015, edef +// See the LICENSE file included in this distribution. +use void::Void; + +use stack::Stack; +use arch::common::{push, rust_trampoline}; + +pub const STACK_ALIGN: usize = 16; + +#[derive(Debug)] +pub struct Registers { + stack_pointer: *mut usize +} + +impl Registers { + #[inline] + pub unsafe fn new(stack: &mut S, f: F) -> Registers + where S: Stack, F: FnOnce() -> Void + { + let mut sp = stack.top() as *mut usize; + let f_ptr = push(&mut sp, f); + + init!(sp, f_ptr, rust_trampoline:: as unsafe extern "C" fn(*const F) -> !); + + Registers { + stack_pointer: sp, + } + } + + #[inline(always)] + pub unsafe fn swap(out_regs: *mut Registers, in_regs: *const Registers) { + swap!(&mut (*out_regs).stack_pointer, &(*in_regs).stack_pointer); + } +}