From 34a384a128d9630679f9c90bb27eaa0822e5b798 Mon Sep 17 00:00:00 2001 From: Pawel Olzacki <p.olzacki2@samsung.com> Date: Tue, 17 Jun 2014 09:16:03 +0200 Subject: [PATCH] Added Mipsel architecture support --- mk/platform.mk | 32 ++++++++++- src/libcore/mem.rs | 2 + src/libgreen/context.rs | 3 + src/liblibc/lib.rs | 8 +++ src/libnative/io/c_unix.rs | 15 ++++- src/librustc/back/mipsel.rs | 72 ++++++++++++++++++++++++ src/librustc/driver/config.rs | 12 ++-- src/librustc/lib.rs | 1 + src/librustc/middle/trans/adt.rs | 3 +- src/librustc/middle/trans/asm.rs | 1 + src/librustc/middle/trans/base.rs | 6 +- src/librustc/middle/trans/cabi.rs | 3 +- src/librustc/middle/trans/type_.rs | 4 +- src/librustrt/libunwind.rs | 1 + src/librustrt/mutex.rs | 4 ++ src/librustrt/stack.rs | 2 + src/libstd/os.rs | 4 ++ src/libsyntax/abi.rs | 3 +- src/rt/arch/mipsel/_context.S | 88 ++++++++++++++++++++++++++++++ src/rt/arch/mipsel/morestack.S | 43 +++++++++++++++ src/rt/arch/mipsel/record_sp.S | 40 ++++++++++++++ 21 files changed, 331 insertions(+), 16 deletions(-) create mode 100644 src/librustc/back/mipsel.rs create mode 100644 src/rt/arch/mipsel/_context.S create mode 100644 src/rt/arch/mipsel/morestack.S create mode 100644 src/rt/arch/mipsel/record_sp.S diff --git a/mk/platform.mk b/mk/platform.mk index 1efa1cc5b6d85..3c6296d610aac 100644 --- a/mk/platform.mk +++ b/mk/platform.mk @@ -374,6 +374,36 @@ CFG_RUN_TARG_arm-unknown-linux-gnueabi=$(call CFG_RUN_arm-unknown-linux-gnueabi, RUSTC_FLAGS_arm-unknown-linux-gnueabi := RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi := +# mipsel-linux configuration +CC_mipsel-linux=mipsel-linux-gcc +CXX_mipsel-linux=mipsel-linux-g++ +CPP_mipsel-linux=mipsel-linux-gcc +AR_mipsel-linux=mipsel-linux-ar +CFG_LIB_NAME_mipsel-linux=lib$(1).so +CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a +CFG_LIB_GLOB_mipsel-linux=lib$(1)-*.so +CFG_LIB_DSYM_GLOB_mipsel-linux=lib$(1)-*.dylib.dSYM +CFG_CFLAGS_mipsel-linux := -mips32 -mabi=32 $(CFLAGS) +CFG_GCCISH_CFLAGS_mipsel-linux := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS) +CFG_GCCISH_CXXFLAGS_mipsel-linux := -fno-rtti $(CXXFLAGS) +CFG_GCCISH_LINK_FLAGS_mipsel-linux := -shared -fPIC -g -mips32 +CFG_GCCISH_DEF_FLAG_mipsel-linux := -Wl,--export-dynamic,--dynamic-list= +CFG_GCCISH_PRE_LIB_FLAGS_mipsel-linux := -Wl,-whole-archive +CFG_GCCISH_POST_LIB_FLAGS_mipsel-linux := -Wl,-no-whole-archive +CFG_DEF_SUFFIX_mipsel-linux := .linux.def +CFG_LLC_FLAGS_mipsel-linux := +CFG_INSTALL_NAME_mipsel-linux = +CFG_LIBUV_LINK_FLAGS_mipsel-linux = +CFG_EXE_SUFFIX_mipsel-linux := +CFG_WINDOWSY_mipsel-linux := +CFG_UNIXY_mipsel-linux := 1 +CFG_PATH_MUNGE_mipsel-linux := true +CFG_LDPATH_mipsel-linux := +CFG_RUN_mipsel-linux= +CFG_RUN_TARG_mipsel-linux= +RUSTC_FLAGS_mipsel-linux := -C target-cpu=mips32 -C target-feature="+mips32,+o32" + + # mips-unknown-linux-gnu configuration CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++ @@ -612,7 +642,7 @@ define CFG_MAKE_TOOLCHAIN $$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \ $$(call CFG_INSTALL_NAME_$(1),$$(4)) - ifeq ($$(findstring $(HOST_$(1)),arm mips),) + ifeq ($$(findstring $(HOST_$(1)),arm mips mipsel),) # We're using llvm-mc as our assembler because it supports # .cfi pseudo-ops on mac diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 237efcd0096d0..a04afd59ecee1 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -470,6 +470,7 @@ mod tests { #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] fn size_of_32() { assert_eq!(size_of::<uint>(), 4u); assert_eq!(size_of::<*uint>(), 4u); @@ -501,6 +502,7 @@ mod tests { #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] fn align_of_32() { assert_eq!(align_of::<uint>(), 4u); assert_eq!(align_of::<*uint>(), 4u); diff --git a/src/libgreen/context.rs b/src/libgreen/context.rs index e6915385a42d5..f11a1d2c66737 100644 --- a/src/libgreen/context.rs +++ b/src/libgreen/context.rs @@ -268,12 +268,15 @@ fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint, } #[cfg(target_arch = "mips")] +#[cfg(target_arch = "mipsel")] type Registers = [uint, ..32]; #[cfg(target_arch = "mips")] +#[cfg(target_arch = "mipsel")] fn new_regs() -> Box<Registers> { box {[0, .. 32]} } #[cfg(target_arch = "mips")] +#[cfg(target_arch = "mipsel")] fn initialize_call_frame(regs: &mut Registers, fptr: InitFn, arg: uint, procedure: raw::Procedure, sp: *mut uint) { let sp = align_down(sp); diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 9ed0d50a03e8a..2aa84a337f298 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -463,6 +463,7 @@ pub mod types { #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] pub mod arch { pub mod c95 { pub type c_char = i8; @@ -491,6 +492,7 @@ pub mod types { } #[cfg(target_arch = "x86")] #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] pub mod posix88 { pub type off_t = i32; pub type dev_t = u64; @@ -599,6 +601,7 @@ pub mod types { } } #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] pub mod posix01 { use types::os::arch::c95::{c_long, c_ulong, time_t}; use types::os::arch::posix88::{gid_t, ino_t}; @@ -2209,6 +2212,7 @@ pub mod consts { } #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] pub mod posix88 { use types::os::arch::c95::c_int; use types::common::c95::c_void; @@ -2483,6 +2487,7 @@ pub mod consts { pub static PTHREAD_STACK_MIN: size_t = 16384; #[cfg(target_arch = "mips", target_os = "linux")] + #[cfg(target_arch = "mipsel", target_os = "linux")] pub static PTHREAD_STACK_MIN: size_t = 131072; pub static CLOCK_REALTIME: c_int = 0; @@ -2536,6 +2541,7 @@ pub mod consts { pub static SHUT_RDWR: c_int = 2; } #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] pub mod bsd44 { use types::os::arch::c95::c_int; @@ -2604,6 +2610,7 @@ pub mod consts { pub static MAP_STACK : c_int = 0x020000; } #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] pub mod extra { use types::os::arch::c95::c_int; @@ -2976,6 +2983,7 @@ pub mod consts { pub static PTHREAD_STACK_MIN: size_t = 4096; #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] #[cfg(target_arch = "x86")] #[cfg(target_arch = "x86_64")] pub static PTHREAD_STACK_MIN: size_t = 2048; diff --git a/src/libnative/io/c_unix.rs b/src/libnative/io/c_unix.rs index 70fd6310070da..7a52c04849853 100644 --- a/src/libnative/io/c_unix.rs +++ b/src/libnative/io/c_unix.rs @@ -23,20 +23,26 @@ use libc; #[cfg(target_os = "ios")] #[cfg(target_os = "freebsd")] pub static FIONBIO: libc::c_ulong = 0x8004667e; -#[cfg(target_os = "linux", not(target_arch = "mips"))] +#[cfg(target_os = "linux", target_arch = "x86")] +#[cfg(target_os = "linux", target_arch = "x86_64")] +#[cfg(target_os = "linux", target_arch = "arm")] #[cfg(target_os = "android")] pub static FIONBIO: libc::c_ulong = 0x5421; #[cfg(target_os = "linux", target_arch = "mips")] +#[cfg(target_os = "linux", target_arch = "mipsel")] pub static FIONBIO: libc::c_ulong = 0x667e; #[cfg(target_os = "macos")] #[cfg(target_os = "ios")] #[cfg(target_os = "freebsd")] pub static FIOCLEX: libc::c_ulong = 0x20006601; -#[cfg(target_os = "linux", not(target_arch = "mips"))] +#[cfg(target_os = "linux", target_arch = "x86")] +#[cfg(target_os = "linux", target_arch = "x86_64")] +#[cfg(target_os = "linux", target_arch = "arm")] #[cfg(target_os = "android")] pub static FIOCLEX: libc::c_ulong = 0x5451; #[cfg(target_os = "linux", target_arch = "mips")] +#[cfg(target_os = "linux", target_arch = "mipsel")] pub static FIOCLEX: libc::c_ulong = 0x6601; #[cfg(target_os = "macos")] @@ -109,7 +115,9 @@ mod select { } } -#[cfg(target_os = "linux", not(target_arch = "mips"))] +#[cfg(target_os = "linux", target_arch = "x86")] +#[cfg(target_os = "linux", target_arch = "x86_64")] +#[cfg(target_os = "linux", target_arch = "arm")] #[cfg(target_os = "android")] mod signal { use libc; @@ -153,6 +161,7 @@ mod signal { } #[cfg(target_os = "linux", target_arch = "mips")] +#[cfg(target_os = "linux", target_arch = "mipsel")] mod signal { use libc; diff --git a/src/librustc/back/mipsel.rs b/src/librustc/back/mipsel.rs new file mode 100644 index 0000000000000..c2c48a41e8fe0 --- /dev/null +++ b/src/librustc/back/mipsel.rs @@ -0,0 +1,72 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use back::target_strs; +use syntax::abi; + +pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t { + return target_strs::t { + module_asm: "".to_string(), + + data_layout: match target_os { + abi::OsMacos => { + "e-p:32:32:32\ + -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ + -f32:32:32-f64:64:64\ + -v64:64:64-v128:64:128\ + -a0:0:64-n32".to_string() + } + + abi::OsiOS => { + "e-p:32:32:32\ + -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ + -f32:32:32-f64:64:64\ + -v64:64:64-v128:64:128\ + -a0:0:64-n32".to_string() + } + + abi::OsWin32 => { + "e-p:32:32:32\ + -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ + -f32:32:32-f64:64:64\ + -v64:64:64-v128:64:128\ + -a0:0:64-n32".to_string() + } + + abi::OsLinux => { + "e-p:32:32:32\ + -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ + -f32:32:32-f64:64:64\ + -v64:64:64-v128:64:128\ + -a0:0:64-n32".to_string() + } + + abi::OsAndroid => { + "e-p:32:32:32\ + -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ + -f32:32:32-f64:64:64\ + -v64:64:64-v128:64:128\ + -a0:0:64-n32".to_string() + } + + abi::OsFreebsd => { + "e-p:32:32:32\ + -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\ + -f32:32:32-f64:64:64\ + -v64:64:64-v128:64:128\ + -a0:0:64-n32".to_string() + } + }, + + target_triple: target_triple, + + cc_args: Vec::new(), + }; +} diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index db96330d656fe..95e0af028fa40 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -18,7 +18,7 @@ use driver::session::Session; use back; use back::link; use back::target_strs; -use back::{arm, x86, x86_64, mips}; +use back::{arm, x86, x86_64, mips, mipsel}; use middle::lint; use syntax::abi; @@ -373,7 +373,8 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { abi::X86 => ("little", "x86", "32"), abi::X86_64 => ("little", "x86_64", "64"), abi::Arm => ("little", "arm", "32"), - abi::Mips => ("big", "mips", "32") + abi::Mips => ("big", "mips", "32"), + abi::Mipsel => ("little", "mipsel", "32") }; let fam = match sess.targ_cfg.os { @@ -452,6 +453,7 @@ static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'stat ("xscale", abi::Arm), ("thumb", abi::Arm), + ("mipsel", abi::Mipsel), ("mips", abi::Mips)]; pub fn build_target_config(sopts: &Options) -> Config { @@ -470,14 +472,16 @@ pub fn build_target_config(sopts: &Options) -> Config { abi::X86 => (ast::TyI32, ast::TyU32), abi::X86_64 => (ast::TyI64, ast::TyU64), abi::Arm => (ast::TyI32, ast::TyU32), - abi::Mips => (ast::TyI32, ast::TyU32) + abi::Mips => (ast::TyI32, ast::TyU32), + abi::Mipsel => (ast::TyI32, ast::TyU32) }; let target_triple = sopts.target_triple.clone(); let target_strs = match arch { abi::X86 => x86::get_target_strs(target_triple, os), abi::X86_64 => x86_64::get_target_strs(target_triple, os), abi::Arm => arm::get_target_strs(target_triple, os), - abi::Mips => mips::get_target_strs(target_triple, os) + abi::Mips => mips::get_target_strs(target_triple, os), + abi::Mipsel => mipsel::get_target_strs(target_triple, os) }; Config { os: os, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 680bd667c3f0d..e6f9ae0212497 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -97,6 +97,7 @@ pub mod back { pub mod link; pub mod lto; pub mod mips; + pub mod mipsel; pub mod rpath; pub mod svh; pub mod target_strs; diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 1b530ea342491..cbec0125cc579 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -60,7 +60,7 @@ use middle::trans::type_::Type; use middle::trans::type_of; use middle::ty; use middle::ty::Disr; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel}; use syntax::ast; use syntax::attr; use syntax::attr::IntType; @@ -367,6 +367,7 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp // corresponding to `choose_shortest`. However, we don't run on those yet...? Arm => at_least_32, Mips => at_least_32, + Mipsel => at_least_32, } } attr::ReprAny => { diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 871b75760f1d0..81bb50a83afdf 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -135,6 +135,7 @@ pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::InlineAsm) #[cfg(target_arch = "arm")] #[cfg(target_arch = "mips")] +#[cfg(target_arch = "mipsel")] fn get_clobbers() -> String { "".to_string() } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 4657c8cd13654..6f7a90ad040b9 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -83,7 +83,7 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; use std::{i8, i16, i32, i64}; use std::gc::Gc; -use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic}; +use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel, Rust, RustIntrinsic}; use syntax::ast_util::{local_def, is_local}; use syntax::attr::AttrMetaMethods; use syntax::attr; @@ -1021,7 +1021,7 @@ pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); let key = match ccx.sess().targ_cfg.arch { - X86 | Arm | Mips => "llvm.memcpy.p0i8.p0i8.i32", + X86 | Arm | Mips | Mipsel => "llvm.memcpy.p0i8.p0i8.i32", X86_64 => "llvm.memcpy.p0i8.p0i8.i64" }; let memcpy = ccx.get_intrinsic(&key); @@ -1065,7 +1065,7 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { let ccx = b.ccx; let intrinsic_key = match ccx.sess().targ_cfg.arch { - X86 | Arm | Mips => "llvm.memset.p0i8.i32", + X86 | Arm | Mips | Mipsel => "llvm.memset.p0i8.i32", X86_64 => "llvm.memset.p0i8.i64" }; diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 02671b1186631..df1347f6d8f10 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -16,7 +16,7 @@ use middle::trans::cabi_x86_64; use middle::trans::cabi_arm; use middle::trans::cabi_mips; use middle::trans::type_::Type; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel}; #[deriving(Clone, PartialEq)] pub enum ArgKind { @@ -110,5 +110,6 @@ pub fn compute_abi_info(ccx: &CrateContext, X86_64 => cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def), Arm => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def), Mips => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def), + Mipsel => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def), } } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 5d58500f761a4..0d20b704ed86d 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -16,7 +16,7 @@ use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; use middle::trans::context::CrateContext; use syntax::ast; -use syntax::abi::{X86, X86_64, Arm, Mips}; +use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel}; use std::c_str::ToCStr; use std::mem; @@ -106,7 +106,7 @@ impl Type { pub fn int(ccx: &CrateContext) -> Type { match ccx.tcx.sess.targ_cfg.arch { - X86 | Arm | Mips => Type::i32(ccx), + X86 | Arm | Mips | Mipsel => Type::i32(ccx), X86_64 => Type::i64(ccx) } } diff --git a/src/librustrt/libunwind.rs b/src/librustrt/libunwind.rs index 2d58c1bee15bd..fe9b2b569c060 100644 --- a/src/librustrt/libunwind.rs +++ b/src/librustrt/libunwind.rs @@ -69,6 +69,7 @@ pub static unwinder_private_data_size: int = 20; pub static unwinder_private_data_size: int = 5; #[cfg(target_arch = "mips")] +#[cfg(target_arch = "mipsel")] pub static unwinder_private_data_size: int = 2; pub struct _Unwind_Exception { diff --git a/src/librustrt/mutex.rs b/src/librustrt/mutex.rs index ee696f2cf7c08..2bbfcf73917c9 100644 --- a/src/librustrt/mutex.rs +++ b/src/librustrt/mutex.rs @@ -415,6 +415,8 @@ mod imp { static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8; #[cfg(target_arch = "mips")] static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8; + #[cfg(target_arch = "mipsel")] + static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8; #[cfg(target_arch = "x86_64")] static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8; #[cfg(target_arch = "x86")] @@ -423,6 +425,8 @@ mod imp { static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8; #[cfg(target_arch = "mips")] static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8; + #[cfg(target_arch = "mipsel")] + static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8; #[repr(C)] pub struct pthread_mutex_t { diff --git a/src/librustrt/stack.rs b/src/librustrt/stack.rs index e6fa845bedc89..b90f1a0f493f4 100644 --- a/src/librustrt/stack.rs +++ b/src/librustrt/stack.rs @@ -217,6 +217,7 @@ pub unsafe fn record_sp_limit(limit: uint) { // mips, arm - Some brave soul can port these to inline asm, but it's over // my head personally #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] #[cfg(target_arch = "arm", not(target_os = "ios"))] #[inline(always)] unsafe fn target_record_sp_limit(limit: uint) { use libc::c_void; @@ -298,6 +299,7 @@ pub unsafe fn get_sp_limit() -> uint { // mips, arm - Some brave soul can port these to inline asm, but it's over // my head personally #[cfg(target_arch = "mips")] + #[cfg(target_arch = "mipsel")] #[cfg(target_arch = "arm", not(target_os = "ios"))] #[inline(always)] unsafe fn target_get_sp_limit() -> uint { use libc::c_void; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index f6b1c04dd34c6..25b7befd74e97 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1726,6 +1726,10 @@ mod arch_consts { pub static ARCH: &'static str = "mips"; } +#[cfg(target_arch = "mipsel")] +mod arch_consts { + pub static ARCH: &'static str = "mipsel"; +} #[cfg(test)] mod tests { diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 7ff020d6818e1..3d6266fd4c09d 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -41,7 +41,8 @@ pub enum Architecture { X86, X86_64, Arm, - Mips + Mips, + Mipsel } static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint)); diff --git a/src/rt/arch/mipsel/_context.S b/src/rt/arch/mipsel/_context.S new file mode 100644 index 0000000000000..cfe77cc30456b --- /dev/null +++ b/src/rt/arch/mipsel/_context.S @@ -0,0 +1,88 @@ +// Mark stack as non-executable +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack, "", @progbits +#endif + +.text +.globl rust_swap_registers +.align 2 +.set nomips16 +.ent rust_swap_registers +rust_swap_registers: + .set noreorder + .set nomacro + .set noat + sw $1, 1 * 4($4) + sw $2, 2 * 4($4) + sw $3, 3 * 4($4) + sw $4, 4 * 4($4) + sw $5, 5 * 4($4) + sw $6, 6 * 4($4) + sw $7, 7 * 4($4) + + sw $8, 8 * 4($4) + sw $9, 9 * 4($4) + sw $10, 10 * 4($4) + sw $11, 11 * 4($4) + sw $12, 12 * 4($4) + sw $13, 13 * 4($4) + sw $14, 14 * 4($4) + sw $15, 15 * 4($4) + + sw $16, 16 * 4($4) + sw $17, 17 * 4($4) + sw $18, 18 * 4($4) + sw $19, 19 * 4($4) + sw $20, 20 * 4($4) + sw $21, 21 * 4($4) + sw $22, 22 * 4($4) + sw $23, 23 * 4($4) + + sw $24, 24 * 4($4) + sw $25, 25 * 4($4) + sw $26, 26 * 4($4) + sw $27, 27 * 4($4) + sw $28, 28 * 4($4) + sw $29, 29 * 4($4) + sw $30, 30 * 4($4) + sw $31, 31 * 4($4) + + lw $1, 1 * 4($5) + lw $2, 2 * 4($5) + lw $3, 3 * 4($5) + lw $4, 4 * 4($5) + lw $6, 6 * 4($5) + lw $7, 7 * 4($5) + + lw $8, 8 * 4($5) + lw $9, 9 * 4($5) + lw $10, 10 * 4($5) + lw $11, 11 * 4($5) + lw $12, 12 * 4($5) + lw $13, 13 * 4($5) + lw $14, 14 * 4($5) + lw $15, 15 * 4($5) + + lw $16, 16 * 4($5) + lw $17, 17 * 4($5) + lw $18, 18 * 4($5) + lw $19, 19 * 4($5) + lw $20, 20 * 4($5) + lw $21, 21 * 4($5) + lw $22, 22 * 4($5) + lw $23, 23 * 4($5) + + lw $24, 24 * 4($5) + lw $25, 25 * 4($5) + lw $26, 26 * 4($5) + lw $27, 27 * 4($5) + lw $28, 28 * 4($5) + lw $29, 29 * 4($5) + lw $30, 30 * 4($5) + lw $31, 31 * 4($5) + + lw $5, 5 * 4($5) + + jr $31 + nop +.end rust_swap_registers diff --git a/src/rt/arch/mipsel/morestack.S b/src/rt/arch/mipsel/morestack.S new file mode 100644 index 0000000000000..266933df8c51c --- /dev/null +++ b/src/rt/arch/mipsel/morestack.S @@ -0,0 +1,43 @@ +// Mark stack as non-executable +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack, "", @progbits +#endif + +/* See i386/morestack.S for the lengthy, general explanation. */ + +.text + +.globl rust_stack_exhausted +.globl __morestack + +.hidden __morestack + +.cfi_startproc +.set nomips16 +.ent __morestack +__morestack: + .set noreorder + .set nomacro + + addiu $29, $29, -4 + sw $30, 0($29) + + // 16 = 4 (current) + 12 (previous) + .cfi_def_cfa_offset 16 + .cfi_offset 31, -4 + .cfi_offset 30, -16 + + move $30, $29 + .cfi_def_cfa_register 30 + + // O32 ABI always reserves 16 bytes for arguments + addiu $29, $29, -16 + + lw $25, %call16(rust_stack_exhausted)($28) + jalr $25 + nop + + // the above function make sure that we never get here + +.end __morestack +.cfi_endproc diff --git a/src/rt/arch/mipsel/record_sp.S b/src/rt/arch/mipsel/record_sp.S new file mode 100644 index 0000000000000..a6dfa04edbbd7 --- /dev/null +++ b/src/rt/arch/mipsel/record_sp.S @@ -0,0 +1,40 @@ +// Mark stack as non-executable +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack, "", @progbits +#endif + +.text + +.globl record_sp_limit +.align 2 +.set nomips16 +.ent record_sp_limit +record_sp_limit: + .set noreorder + .set nomacro + .set push + .set mips32r2 + rdhwr $3, $29 + .set pop + addiu $3, $3, -0x7004 + sw $4, 0($3) + jr $31 + nop +.end record_sp_limit + +.globl get_sp_limit +.align 2 +.set nomips16 +.ent get_sp_limit +get_sp_limit: + .set noreorder + .set nomacro + .set push + .set mips32r2 + rdhwr $3, $29 + .set pop + addiu $3, $3, -0x7004 + lw $2, 0($3) + jr $31 + nop +.end get_sp_limit