Skip to content

Commit

Permalink
libgreen: use FFI-safe types
Browse files Browse the repository at this point in the history
  • Loading branch information
emberian committed Aug 21, 2014
1 parent 2dc2ac1 commit cf5d280
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 31 deletions.
10 changes: 10 additions & 0 deletions src/libcore/simd.rs
Expand Up @@ -40,6 +40,7 @@
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
pub i8, pub i8, pub i8, pub i8,
pub i8, pub i8, pub i8, pub i8,
Expand All @@ -48,22 +49,26 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
pub i16, pub i16, pub i16, pub i16);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct i64x2(pub i64, pub i64);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
pub u8, pub u8, pub u8, pub u8,
pub u8, pub u8, pub u8, pub u8,
Expand All @@ -72,25 +77,30 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
pub u16, pub u16, pub u16, pub u16);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct u64x2(pub u64, pub u64);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);

#[experimental]
#[simd]
#[deriving(Show)]
#[repr(C)]
pub struct f64x2(pub f64, pub f64);
61 changes: 32 additions & 29 deletions src/libgreen/context.rs
Expand Up @@ -15,6 +15,7 @@ use std::rt::stack;
use std::raw;
#[cfg(target_arch = "x86_64")]
use std::simd;
use libc;

// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs. It would be marginally better not to do this. In C++ we
Expand Down Expand Up @@ -69,7 +70,7 @@ impl Context {
// overflow). Additionally, their coroutine stacks are listed as being
// zero-length, so that's how we detect what's what here.
let stack_base: *const uint = stack.start();
let bounds = if sp as uint == stack_base as uint {
let bounds = if sp as libc::uintptr_t == stack_base as libc::uintptr_t {
None
} else {
Some((stack_base as uint, sp as uint))
Expand Down Expand Up @@ -165,16 +166,16 @@ fn new_regs() -> Box<Registers> {

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
procedure: raw::Procedure, sp: *mut uint) {
procedure: raw::Procedure, sp: *mut libc::uintptr_t) {

// x86 has interesting stack alignment requirements, so do some alignment
// plus some offsetting to figure out what the actual stack should be.
let sp = align_down(sp);
let sp = mut_offset(sp, -4);

unsafe { *mut_offset(sp, 2) = procedure.env as uint };
unsafe { *mut_offset(sp, 1) = procedure.code as uint };
unsafe { *mut_offset(sp, 0) = arg as uint };
unsafe { *mut_offset(sp, 2) = procedure.env as libc::uintptr_t };
unsafe { *mut_offset(sp, 1) = procedure.code as libc::uintptr_t };
unsafe { *mut_offset(sp, 0) = arg as libc::uintptr_t };
let sp = mut_offset(sp, -1);
unsafe { *sp = 0 }; // The final return address

Expand All @@ -188,13 +189,15 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
// windows requires saving more registers (both general and XMM), so the windows
// register context must be larger.
#[cfg(windows, target_arch = "x86_64")]
#[repr(C)]
struct Registers {
gpr:[uint, ..14],
gpr:[libc::uintptr_t, ..14],
_xmm:[simd::u32x4, ..10]
}
#[cfg(not(windows), target_arch = "x86_64")]
#[repr(C)]
struct Registers {
gpr:[uint, ..10],
gpr:[libc::uintptr_t, ..10],
_xmm:[simd::u32x4, ..6]
}

Expand Down Expand Up @@ -234,30 +237,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
unsafe { *sp = 0; }

rtdebug!("creating call frame");
rtdebug!("fptr {:#x}", fptr as uint);
rtdebug!("fptr {:#x}", fptr as libc::uintptr_t);
rtdebug!("arg {:#x}", arg);
rtdebug!("sp {}", sp);

// These registers are frobbed by rust_bootstrap_green_task into the right
// location so we can invoke the "real init function", `fptr`.
regs.gpr[RUSTRT_R12] = arg as uint;
regs.gpr[RUSTRT_R13] = procedure.code as uint;
regs.gpr[RUSTRT_R14] = procedure.env as uint;
regs.gpr[RUSTRT_R15] = fptr as uint;
regs.gpr[RUSTRT_R12] = arg as libc::uintptr_t;
regs.gpr[RUSTRT_R13] = procedure.code as libc::uintptr_t;
regs.gpr[RUSTRT_R14] = procedure.env as libc::uintptr_t;
regs.gpr[RUSTRT_R15] = fptr as libc::uintptr_t;

// These registers are picked up by the regular context switch paths. These
// will put us in "mostly the right context" except for frobbing all the
// arguments to the right place. We have the small trampoline code inside of
// rust_bootstrap_green_task to do that.
regs.gpr[RUSTRT_RSP] = sp as uint;
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint;
regs.gpr[RUSTRT_RSP] = sp as libc::uintptr_t;
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as libc::uintptr_t;

// Last base pointer on the stack should be 0
regs.gpr[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];
type Registers = [libc::uintptr_t, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> Box<Registers> { box {[0, .. 32]} }
Expand All @@ -277,17 +280,17 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
// ARM uses the same technique as x86_64 to have a landing pad for the start
// of all new green tasks. Neither r1/r2 are saved on a context switch, so
// the shim will copy r3/r4 into r1/r2 and then execute the function in r5
regs[0] = arg as uint; // r0
regs[3] = procedure.code as uint; // r3
regs[4] = procedure.env as uint; // r4
regs[5] = fptr as uint; // r5
regs[13] = sp as uint; // #52 sp, r13
regs[14] = rust_bootstrap_green_task as uint; // #56 pc, r14 --> lr
regs[0] = arg as libc::uintptr_t; // r0
regs[3] = procedure.code as libc::uintptr_t; // r3
regs[4] = procedure.env as libc::uintptr_t; // r4
regs[5] = fptr as libc::uintptr_t; // r5
regs[13] = sp as libc::uintptr_t; // #52 sp, r13
regs[14] = rust_bootstrap_green_task as libc::uintptr_t; // #56 pc, r14 --> lr
}

#[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")]
type Registers = [uint, ..32];
type Registers = [libc::uintptr_t, ..32];

#[cfg(target_arch = "mips")]
#[cfg(target_arch = "mipsel")]
Expand All @@ -304,16 +307,16 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
// The final return address. 0 indicates the bottom of the stack
unsafe { *sp = 0; }

regs[4] = arg as uint;
regs[5] = procedure.code as uint;
regs[6] = procedure.env as uint;
regs[29] = sp as uint;
regs[25] = fptr as uint;
regs[31] = fptr as uint;
regs[4] = arg as libc::uintptr_t;
regs[5] = procedure.code as libc::uintptr_t;
regs[6] = procedure.env as libc::uintptr_t;
regs[29] = sp as libc::uintptr_t;
regs[25] = fptr as libc::uintptr_t;
regs[31] = fptr as libc::uintptr_t;
}

fn align_down(sp: *mut uint) -> *mut uint {
let sp = (sp as uint) & !(16 - 1);
let sp = (sp as libc::uintptr_t) & !(16 - 1);
sp as *mut uint
}

Expand Down
2 changes: 1 addition & 1 deletion src/libgreen/stack.rs
Expand Up @@ -68,7 +68,7 @@ impl Stack {

// FIXME: Using the FFI to call a C macro. Slow
stk.valgrind_id = unsafe {
rust_valgrind_stack_register(stk.start(), stk.end())
rust_valgrind_stack_register(stk.start() as *const libc::uintptr_t, stk.end() as *const libc::uintptr_t)
};
return stk;
}
Expand Down
3 changes: 2 additions & 1 deletion src/libnative/io/c_unix.rs
Expand Up @@ -107,13 +107,14 @@ mod select {
#[cfg(target_os = "linux")]
mod select {
use std::uint;
use libc;

pub static FD_SETSIZE: uint = 1024;

#[repr(C)]
pub struct fd_set {
// FIXME: shouldn't this be a c_ulong?
fds_bits: [uint, ..(FD_SETSIZE / uint::BITS)]
fds_bits: [libc::uintptr_t, ..(FD_SETSIZE / uint::BITS)]
}

pub fn fd_set(set: &mut fd_set, fd: i32) {
Expand Down

0 comments on commit cf5d280

Please sign in to comment.