Factor out common code between x86 and x86_64

Fix #17
This commit is contained in:
John Ericson 2016-04-10 22:15:01 -07:00 committed by edef
parent c51290f8e7
commit 35fb046fb5
3 changed files with 91 additions and 85 deletions

View File

@ -1,48 +1,33 @@
// This file is part of libfringe, a low-level green threading library. // This file is part of libfringe, a low-level green threading library.
// Copyright (c) edef <edef@edef.eu> // Copyright (c) edef <edef@edef.eu>
// See the LICENSE file included in this distribution. // See the LICENSE file included in this distribution.
use void::Void; pub use self::common::*;
use stack::Stack; macro_rules! init {
use super::common::{push, rust_trampoline}; ($sp:expr, $f_ptr:expr, $tramp:expr) => {
asm!(include_str!("x86/init.s")
pub const STACK_ALIGN: usize = 16; : "={eax}"($sp)
: "{eax}" ($sp),
#[derive(Debug)] "{ebx}" ($tramp),
pub struct Registers { "{ecx}" ($f_ptr)
esp: *mut usize :
: "volatile")
};
} }
impl Registers { macro_rules! swap {
#[inline] ($out_spp:expr, $in_spp:expr) => {
pub unsafe fn new<S, F>(stack: &mut S, f: F) -> Registers asm!(include_str!("x86/swap.s")
where S: Stack, F: FnOnce() -> Void { :
let mut sp = stack.top() as *mut usize; : "{eax}" ($out_spp),
let f_ptr = push(&mut sp, f); "{ebx}" ($in_spp)
: "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp",
asm!(include_str!("init.s") "mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
: "={eax}"(sp) "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
: "{eax}" (sp), "cc"
"{ebx}" (rust_trampoline::<F> as unsafe extern "C" fn(*const F) -> !), : "volatile")
"{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");
}
} }
#[path = "../x86_common.rs"]
mod common;

View File

@ -1,50 +1,36 @@
// This file is part of libfringe, a low-level green threading library. // This file is part of libfringe, a low-level green threading library.
// Copyright (c) edef <edef@edef.eu> // Copyright (c) edef <edef@edef.eu>
// See the LICENSE file included in this distribution. // See the LICENSE file included in this distribution.
use stack::Stack; pub use self::common::*;
use void::Void;
use super::common::{push, rust_trampoline};
pub const STACK_ALIGN: usize = 16; macro_rules! init {
($sp:expr, $f_ptr:expr, $tramp:expr) => {
#[derive(Debug)] asm!(include_str!("x86_64/init.s")
pub struct Registers { : "={rdi}"($sp)
rsp: *mut usize : "{rdi}" ($sp),
} "{rsi}" ($tramp),
"{rdx}" ($f_ptr)
impl Registers { :
#[inline] : "volatile");
pub unsafe fn new<S, F>(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::<F> 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! 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;

35
src/arch/x86_common.rs Normal file
View File

@ -0,0 +1,35 @@
// This file is part of libfringe, a low-level green threading library.
// Copyright (c) 2015, edef <edef@edef.eu>
// 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<S, F>(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::<F> 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);
}
}