libgreen: use FFI-safe types
This commit is contained in:
@@ -40,6 +40,7 @@
|
|||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
|
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,
|
||||||
pub i8, pub i8, pub i8, pub i8,
|
pub i8, pub i8, pub i8, pub i8,
|
||||||
@@ -48,22 +49,26 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
|
|||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
|
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
|
||||||
pub i16, pub i16, pub i16, pub i16);
|
pub i16, pub i16, pub i16, pub i16);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
|
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct i64x2(pub i64, pub i64);
|
pub struct i64x2(pub i64, pub i64);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
|
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,
|
||||||
pub u8, pub u8, pub u8, pub u8,
|
pub u8, pub u8, pub u8, pub u8,
|
||||||
@@ -72,25 +77,30 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
|
|||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
|
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
|
||||||
pub u16, pub u16, pub u16, pub u16);
|
pub u16, pub u16, pub u16, pub u16);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
|
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct u64x2(pub u64, pub u64);
|
pub struct u64x2(pub u64, pub u64);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
|
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
|
||||||
|
|
||||||
#[experimental]
|
#[experimental]
|
||||||
#[simd]
|
#[simd]
|
||||||
#[deriving(Show)]
|
#[deriving(Show)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct f64x2(pub f64, pub f64);
|
pub struct f64x2(pub f64, pub f64);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use std::rt::stack;
|
|||||||
use std::raw;
|
use std::raw;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use std::simd;
|
use std::simd;
|
||||||
|
use libc;
|
||||||
|
|
||||||
// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
|
// 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
|
// SSE regs. It would be marginally better not to do this. In C++ we
|
||||||
@@ -69,7 +70,7 @@ impl Context {
|
|||||||
// overflow). Additionally, their coroutine stacks are listed as being
|
// overflow). Additionally, their coroutine stacks are listed as being
|
||||||
// zero-length, so that's how we detect what's what here.
|
// zero-length, so that's how we detect what's what here.
|
||||||
let stack_base: *const uint = stack.start();
|
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
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((stack_base as uint, sp as uint))
|
Some((stack_base as uint, sp as uint))
|
||||||
@@ -165,16 +166,16 @@ fn new_regs() -> Box<Registers> {
|
|||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
|
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
|
// x86 has interesting stack alignment requirements, so do some alignment
|
||||||
// plus some offsetting to figure out what the actual stack should be.
|
// plus some offsetting to figure out what the actual stack should be.
|
||||||
let sp = align_down(sp);
|
let sp = align_down(sp);
|
||||||
let sp = mut_offset(sp, -4);
|
let sp = mut_offset(sp, -4);
|
||||||
|
|
||||||
unsafe { *mut_offset(sp, 2) = procedure.env as uint };
|
unsafe { *mut_offset(sp, 2) = procedure.env as libc::uintptr_t };
|
||||||
unsafe { *mut_offset(sp, 1) = procedure.code as uint };
|
unsafe { *mut_offset(sp, 1) = procedure.code as libc::uintptr_t };
|
||||||
unsafe { *mut_offset(sp, 0) = arg as uint };
|
unsafe { *mut_offset(sp, 0) = arg as libc::uintptr_t };
|
||||||
let sp = mut_offset(sp, -1);
|
let sp = mut_offset(sp, -1);
|
||||||
unsafe { *sp = 0 }; // The final return address
|
unsafe { *sp = 0 }; // The final return address
|
||||||
|
|
||||||
@@ -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
|
// windows requires saving more registers (both general and XMM), so the windows
|
||||||
// register context must be larger.
|
// register context must be larger.
|
||||||
#[cfg(windows, target_arch = "x86_64")]
|
#[cfg(windows, target_arch = "x86_64")]
|
||||||
|
#[repr(C)]
|
||||||
struct Registers {
|
struct Registers {
|
||||||
gpr:[uint, ..14],
|
gpr:[libc::uintptr_t, ..14],
|
||||||
_xmm:[simd::u32x4, ..10]
|
_xmm:[simd::u32x4, ..10]
|
||||||
}
|
}
|
||||||
#[cfg(not(windows), target_arch = "x86_64")]
|
#[cfg(not(windows), target_arch = "x86_64")]
|
||||||
|
#[repr(C)]
|
||||||
struct Registers {
|
struct Registers {
|
||||||
gpr:[uint, ..10],
|
gpr:[libc::uintptr_t, ..10],
|
||||||
_xmm:[simd::u32x4, ..6]
|
_xmm:[simd::u32x4, ..6]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,30 +237,30 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint,
|
|||||||
unsafe { *sp = 0; }
|
unsafe { *sp = 0; }
|
||||||
|
|
||||||
rtdebug!("creating call frame");
|
rtdebug!("creating call frame");
|
||||||
rtdebug!("fptr {:#x}", fptr as uint);
|
rtdebug!("fptr {:#x}", fptr as libc::uintptr_t);
|
||||||
rtdebug!("arg {:#x}", arg);
|
rtdebug!("arg {:#x}", arg);
|
||||||
rtdebug!("sp {}", sp);
|
rtdebug!("sp {}", sp);
|
||||||
|
|
||||||
// These registers are frobbed by rust_bootstrap_green_task into the right
|
// These registers are frobbed by rust_bootstrap_green_task into the right
|
||||||
// location so we can invoke the "real init function", `fptr`.
|
// location so we can invoke the "real init function", `fptr`.
|
||||||
regs.gpr[RUSTRT_R12] = arg as uint;
|
regs.gpr[RUSTRT_R12] = arg as libc::uintptr_t;
|
||||||
regs.gpr[RUSTRT_R13] = procedure.code as uint;
|
regs.gpr[RUSTRT_R13] = procedure.code as libc::uintptr_t;
|
||||||
regs.gpr[RUSTRT_R14] = procedure.env as uint;
|
regs.gpr[RUSTRT_R14] = procedure.env as libc::uintptr_t;
|
||||||
regs.gpr[RUSTRT_R15] = fptr as uint;
|
regs.gpr[RUSTRT_R15] = fptr as libc::uintptr_t;
|
||||||
|
|
||||||
// These registers are picked up by the regular context switch paths. These
|
// 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
|
// 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
|
// arguments to the right place. We have the small trampoline code inside of
|
||||||
// rust_bootstrap_green_task to do that.
|
// rust_bootstrap_green_task to do that.
|
||||||
regs.gpr[RUSTRT_RSP] = sp as uint;
|
regs.gpr[RUSTRT_RSP] = sp as libc::uintptr_t;
|
||||||
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as uint;
|
regs.gpr[RUSTRT_IP] = rust_bootstrap_green_task as libc::uintptr_t;
|
||||||
|
|
||||||
// Last base pointer on the stack should be 0
|
// Last base pointer on the stack should be 0
|
||||||
regs.gpr[RUSTRT_RBP] = 0;
|
regs.gpr[RUSTRT_RBP] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
type Registers = [uint, ..32];
|
type Registers = [libc::uintptr_t, ..32];
|
||||||
|
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
fn new_regs() -> Box<Registers> { box {[0, .. 32]} }
|
fn new_regs() -> Box<Registers> { box {[0, .. 32]} }
|
||||||
@@ -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
|
// 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
|
// 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
|
// the shim will copy r3/r4 into r1/r2 and then execute the function in r5
|
||||||
regs[0] = arg as uint; // r0
|
regs[0] = arg as libc::uintptr_t; // r0
|
||||||
regs[3] = procedure.code as uint; // r3
|
regs[3] = procedure.code as libc::uintptr_t; // r3
|
||||||
regs[4] = procedure.env as uint; // r4
|
regs[4] = procedure.env as libc::uintptr_t; // r4
|
||||||
regs[5] = fptr as uint; // r5
|
regs[5] = fptr as libc::uintptr_t; // r5
|
||||||
regs[13] = sp as uint; // #52 sp, r13
|
regs[13] = sp as libc::uintptr_t; // #52 sp, r13
|
||||||
regs[14] = rust_bootstrap_green_task as uint; // #56 pc, r14 --> lr
|
regs[14] = rust_bootstrap_green_task as libc::uintptr_t; // #56 pc, r14 --> lr
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "mips")]
|
#[cfg(target_arch = "mips")]
|
||||||
#[cfg(target_arch = "mipsel")]
|
#[cfg(target_arch = "mipsel")]
|
||||||
type Registers = [uint, ..32];
|
type Registers = [libc::uintptr_t, ..32];
|
||||||
|
|
||||||
#[cfg(target_arch = "mips")]
|
#[cfg(target_arch = "mips")]
|
||||||
#[cfg(target_arch = "mipsel")]
|
#[cfg(target_arch = "mipsel")]
|
||||||
@@ -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
|
// The final return address. 0 indicates the bottom of the stack
|
||||||
unsafe { *sp = 0; }
|
unsafe { *sp = 0; }
|
||||||
|
|
||||||
regs[4] = arg as uint;
|
regs[4] = arg as libc::uintptr_t;
|
||||||
regs[5] = procedure.code as uint;
|
regs[5] = procedure.code as libc::uintptr_t;
|
||||||
regs[6] = procedure.env as uint;
|
regs[6] = procedure.env as libc::uintptr_t;
|
||||||
regs[29] = sp as uint;
|
regs[29] = sp as libc::uintptr_t;
|
||||||
regs[25] = fptr as uint;
|
regs[25] = fptr as libc::uintptr_t;
|
||||||
regs[31] = fptr as uint;
|
regs[31] = fptr as libc::uintptr_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align_down(sp: *mut uint) -> *mut uint {
|
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
|
sp as *mut uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ impl Stack {
|
|||||||
|
|
||||||
// FIXME: Using the FFI to call a C macro. Slow
|
// FIXME: Using the FFI to call a C macro. Slow
|
||||||
stk.valgrind_id = unsafe {
|
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;
|
return stk;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,13 +107,14 @@ mod select {
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod select {
|
mod select {
|
||||||
use std::uint;
|
use std::uint;
|
||||||
|
use libc;
|
||||||
|
|
||||||
pub static FD_SETSIZE: uint = 1024;
|
pub static FD_SETSIZE: uint = 1024;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct fd_set {
|
pub struct fd_set {
|
||||||
// FIXME: shouldn't this be a c_ulong?
|
// 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) {
|
pub fn fd_set(set: &mut fd_set, fd: i32) {
|
||||||
|
|||||||
Reference in New Issue
Block a user