Skip to content

Commit

Permalink
improve MIPS backend and implement segmented stacks
Browse files Browse the repository at this point in the history
  • Loading branch information
crabtw committed May 9, 2013
1 parent fda176b commit c2bf9bf
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 10 deletions.
4 changes: 2 additions & 2 deletions mk/platform.mk
Expand Up @@ -247,12 +247,12 @@ AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32
CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh
CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive -Wl,-znoexecstack
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
CFG_LIBUV_LINK_FLAGS_mips-unknown-linux-gnu =
Expand Down
86 changes: 85 additions & 1 deletion src/libcore/libc.rs
Expand Up @@ -268,14 +268,17 @@ pub mod types {
pub type ssize_t = i32;
}
pub mod posix01 {
use libc::types::os::arch::c95::{c_short, c_long, time_t};
use libc::types::os::arch::c95::{c_short, c_long, c_ulong, time_t};
use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
use libc::types::os::arch::posix88::{mode_t, off_t};
use libc::types::os::arch::posix88::{uid_t};

pub type nlink_t = u32;
pub type blksize_t = i32;
pub type blkcnt_t = i32;

#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
pub struct stat {
st_dev: dev_t,
__pad1: c_short,
Expand All @@ -298,6 +301,30 @@ pub mod types {
__unused4: c_long,
__unused5: c_long,
}

#[cfg(target_arch = "mips")]
pub struct stat {
st_dev: c_ulong,
st_pad1: [c_long, ..3],
st_ino: ino_t,
st_mode: mode_t,
st_nlink: nlink_t,
st_uid: uid_t,
st_gid: gid_t,
st_rdev: c_ulong,
st_pad2: [c_long, ..2],
st_size: off_t,
st_pad3: c_long,
st_atime: time_t,
st_atime_nsec: c_long,
st_mtime: time_t,
st_mtime_nsec: c_long,
st_ctime: time_t,
st_ctime_nsec: c_long,
st_blksize: blksize_t,
st_blocks: blkcnt_t,
st_pad5: [c_long, ..14],
}
}
pub mod posix08 {}
pub mod bsd44 {}
Expand Down Expand Up @@ -963,6 +990,9 @@ pub mod consts {
}
pub mod c99 {
}
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "x86_64")]
#[cfg(target_arch = "arm")]
pub mod posix88 {
pub static O_RDONLY : int = 0;
pub static O_WRONLY : int = 1;
Expand Down Expand Up @@ -1007,6 +1037,51 @@ pub mod consts {
pub static SIGALRM : int = 14;
pub static SIGTERM : int = 15;
}
#[cfg(target_arch = "mips")]
pub mod posix88 {
pub static O_RDONLY : int = 0;
pub static O_WRONLY : int = 1;
pub static O_RDWR : int = 2;
pub static O_APPEND : int = 8;
pub static O_CREAT : int = 256;
pub static O_EXCL : int = 1024;
pub static O_TRUNC : int = 512;
pub static S_IFIFO : int = 4096;
pub static S_IFCHR : int = 8192;
pub static S_IFBLK : int = 24576;
pub static S_IFDIR : int = 16384;
pub static S_IFREG : int = 32768;
pub static S_IFMT : int = 61440;
pub static S_IEXEC : int = 64;
pub static S_IWRITE : int = 128;
pub static S_IREAD : int = 256;
pub static S_IRWXU : int = 448;
pub static S_IXUSR : int = 64;
pub static S_IWUSR : int = 128;
pub static S_IRUSR : int = 256;
pub static F_OK : int = 0;
pub static R_OK : int = 4;
pub static W_OK : int = 2;
pub static X_OK : int = 1;
pub static STDIN_FILENO : int = 0;
pub static STDOUT_FILENO : int = 1;
pub static STDERR_FILENO : int = 2;
pub static F_LOCK : int = 1;
pub static F_TEST : int = 3;
pub static F_TLOCK : int = 2;
pub static F_ULOCK : int = 0;
pub static SIGHUP : int = 1;
pub static SIGINT : int = 2;
pub static SIGQUIT : int = 3;
pub static SIGILL : int = 4;
pub static SIGABRT : int = 6;
pub static SIGFPE : int = 8;
pub static SIGKILL : int = 9;
pub static SIGSEGV : int = 11;
pub static SIGPIPE : int = 13;
pub static SIGALRM : int = 14;
pub static SIGTERM : int = 15;
}
pub mod posix01 {
pub static SIGTRAP : int = 5;

Expand All @@ -1026,11 +1101,20 @@ pub mod consts {
}
pub mod bsd44 {
}
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "x86_64")]
#[cfg(target_arch = "arm")]
pub mod extra {
pub static O_RSYNC : int = 1052672;
pub static O_DSYNC : int = 4096;
pub static O_SYNC : int = 1052672;
}
#[cfg(target_arch = "mips")]
pub mod extra {
pub static O_RSYNC : int = 16400;
pub static O_DSYNC : int = 16;
pub static O_SYNC : int = 16400;
}
}

#[cfg(target_os = "freebsd")]
Expand Down
31 changes: 30 additions & 1 deletion src/libcore/path.rs
Expand Up @@ -122,7 +122,6 @@ pub trait GenericPath {
mod stat {
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
pub mod arch {
use libc;

Expand Down Expand Up @@ -152,6 +151,36 @@ mod stat {
}
}

#[cfg(target_arch = "mips")]
pub mod arch {
use libc;

pub fn default_stat() -> libc::stat {
libc::stat {
st_dev: 0,
st_pad1: [0, ..3],
st_ino: 0,
st_mode: 0,
st_nlink: 0,
st_uid: 0,
st_gid: 0,
st_rdev: 0,
st_pad2: [0, ..2],
st_size: 0,
st_pad3: 0,
st_atime: 0,
st_atime_nsec: 0,
st_mtime: 0,
st_mtime_nsec: 0,
st_ctime: 0,
st_ctime_nsec: 0,
st_blksize: 0,
st_blocks: 0,
st_pad5: [0, ..14],
}
}
}

#[cfg(target_arch = "x86_64")]
pub mod arch {
use libc;
Expand Down
1 change: 1 addition & 0 deletions src/libstd/ebml.rs
Expand Up @@ -157,6 +157,7 @@ pub mod reader {
}

#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
pub fn vuint_at(data: &[u8], start: uint) -> Res {
vuint_at_slow(data, start)
}
Expand Down
1 change: 0 additions & 1 deletion src/rt/arch/mips/ccall.S
Expand Up @@ -8,7 +8,6 @@
.align 2
.globl __morestack
.hidden __morestack
.cfi_sections .eh_frame_entry
.cfi_startproc
.set nomips16
.ent __morestack
Expand Down
97 changes: 97 additions & 0 deletions src/rt/arch/mips/morestack.S
@@ -0,0 +1,97 @@
// Mark stack as non-executable
#if defined(__linux__) && defined(__ELF__)
.section .note.GNU-stack, "", @progbits
#endif

.text

.globl upcall_new_stack
.globl upcall_del_stack
.globl __morestack

.hidden __morestack

.cfi_startproc
.set nomips16
.ent __morestack
__morestack:
.set noreorder
.set nomacro

addiu $29, $29, -12
sw $31, 8($29)
sw $30, 4($29)
sw $23, 0($29)

// 24 = 12 (current) + 12 (previous)
.cfi_def_cfa_offset 24
.cfi_offset 31, -4
.cfi_offset 30, -20
.cfi_offset 23, -24

move $23, $28
move $30, $29
.cfi_def_cfa_register 30

// Save argument registers of the original function
addiu $29, $29, -32
sw $4, 16($29)
sw $5, 20($29)
sw $6, 24($29)
sw $7, 28($29)

move $4, $14 // Size of stack arguments
addu $5, $30, 24 // Address of stack arguments
move $6, $15 // The amount of stack needed

move $28, $23
lw $25, %call16(upcall_new_stack)($23)
jalr $25
nop

// Pop the saved arguments
lw $4, 16($29)
lw $5, 20($29)
lw $6, 24($29)
lw $7, 28($29)
addiu $29, $29, 32

lw $24, 8($30) // Grab the return pointer.
addiu $24, $24, 12 // Skip past the `lw`, `jr`, `addiu` in our parent frame
move $29, $2 // Switch to the new stack.

// for PIC
lw $2, 12($30)
lw $25, 16($30)

move $28, $23
jalr $24 // Reenter the caller function
nop

// Switch back to the rust stack
move $29, $30

// Save the return value
addiu $29, $29, -24
sw $2, 16($29)
sw $3, 20($29)

move $28, $23
lw $25, %call16(upcall_del_stack)($23)
jalr $25
nop

// Restore the return value
lw $2, 16($29)
lw $3, 20($29)
addiu $29, $29, 24

lw $31, 8($29)
lw $30, 4($29)
lw $23, 0($29)
addiu $29, $29, 12

jr $31
nop
.end __morestack
.cfi_endproc
8 changes: 4 additions & 4 deletions src/rt/arch/mips/record_sp.S
Expand Up @@ -16,8 +16,8 @@ record_sp_limit:
.set mips32r2
rdhwr $3, $29
.set pop
addiu $3, $3, -0x7008
sw $4, 4($3)
addiu $3, $3, -0x7004
sw $4, 0($3)
jr $31
nop
.end record_sp_limit
Expand All @@ -33,8 +33,8 @@ get_sp_limit:
.set mips32r2
rdhwr $3, $29
.set pop
addiu $3, $3, -0x7008
lw $2, 4($3)
addiu $3, $3, -0x7004
lw $2, 0($3)
jr $31
nop
.end get_sp_limit
Expand Down
2 changes: 1 addition & 1 deletion src/rt/rust_task.h
Expand Up @@ -144,7 +144,7 @@
#define RED_ZONE_SIZE RZ_LINUX_64
#endif
#ifdef __mips__
#define RED_ZONE_SIZE RZ_LINUX_32
#define RED_ZONE_SIZE RZ_MAC_32
#endif
#endif
#ifdef __APPLE__
Expand Down

5 comments on commit c2bf9bf

@bors
Copy link
Contributor

@bors bors commented on c2bf9bf May 10, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at crabtw@c2bf9bf

@bors
Copy link
Contributor

@bors bors commented on c2bf9bf May 10, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging crabtw/rust/mips-segstk = c2bf9bf into auto

@bors
Copy link
Contributor

@bors bors commented on c2bf9bf May 10, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crabtw/rust/mips-segstk = c2bf9bf merged ok, testing candidate = fdf601e

@bors
Copy link
Contributor

@bors bors commented on c2bf9bf May 10, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on c2bf9bf May 10, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = fdf601e

Please sign in to comment.