Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Support ARM and Android

Conflicts:
	src/libcore/os.rs
	src/librustc/back/link.rs
	src/librustc/driver/driver.rs
	src/librustc/metadata/loader.rs
	src/librustc/middle/trans/base.rs
  • Loading branch information...
commit 987f824f233faee4aed39dac92a1b442d42965cc 1 parent 27e6a0f
@kyeongwoon kyeongwoon authored brson committed
Showing with 599 additions and 30 deletions.
  1. +1 −1  Makefile.in
  2. +1 −1  configure
  3. +3 −0  src/libcore/cleanup.rs
  4. +13 −1 src/libcore/libc.rs
  5. +13 −1 src/libcore/os.rs
  6. +2 −0  src/libcore/path.rs
  7. +2 −0  src/libcore/run.rs
  8. +85 −0 src/librustc/back/arm.rs
  9. +14 −3 src/librustc/back/link.rs
  10. +3 −1 src/librustc/back/rpath.rs
  11. +4 −0 src/librustc/back/x86.rs
  12. +6 −0 src/librustc/back/x86_64.rs
  13. +14 −3 src/librustc/driver/driver.rs
  14. +2 −1  src/librustc/driver/session.rs
  15. +5 −2 src/librustc/metadata/loader.rs
  16. +18 −9 src/librustc/middle/trans/base.rs
  17. +11 −0 src/librustc/middle/trans/foreign.rs
  18. +2 −0  src/librustc/rustc.rc
  19. +2 −0  src/libstd/net_tcp.rs
  20. +15 −0 src/libstd/uv_ll.rs
  21. +47 −0 src/rt/arch/arm/_context.S
  22. +27 −0 src/rt/arch/arm/ccall.S
  23. +36 −0 src/rt/arch/arm/context.cpp
  24. +43 −0 src/rt/arch/arm/context.h
  25. +15 −0 src/rt/arch/arm/gpr.cpp
  26. +23 −0 src/rt/arch/arm/gpr.h
  27. +61 −0 src/rt/arch/arm/record_sp.S
  28. +21 −0 src/rt/arch/arm/regs.h
  29. +61 −0 src/rt/rust_android_dummy.cpp
  30. +5 −0 src/rt/rust_android_dummy.h
  31. +21 −0 src/rt/rust_builtin.cpp
  32. +1 −0  src/rt/rust_sched_loop.cpp
  33. +3 −0  src/rt/rust_task.h
  34. +12 −0 src/rustllvm/RustWrapper.cpp
  35. +7 −7 src/rustllvm/rustllvm.def.in
View
2  Makefile.in
@@ -241,7 +241,7 @@ DRIVER_CRATE := $(S)src/driver/driver.rs
######################################################################
# FIXME: x86-ism
-LLVM_COMPONENTS=x86 ipo bitreader bitwriter linker asmparser jit mcjit \
+LLVM_COMPONENTS=x86 arm ipo bitreader bitwriter linker asmparser jit mcjit \
interpreter
define DEF_LLVM_VARS
View
2  configure
@@ -717,7 +717,7 @@ do
then
msg "configuring LLVM for $t"
- LLVM_TARGETS="--enable-targets=x86,x86_64"
+ LLVM_TARGETS="--enable-targets=x86,x86_64,arm"
LLVM_BUILD="--build=$t"
LLVM_HOST="--host=$t"
LLVM_TARGET="--target=$t"
View
3  src/libcore/cleanup.rs
@@ -40,11 +40,13 @@ struct AllocHeader { priv opaque: () }
struct MemoryRegion { priv opaque: () }
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
struct Registers {
data: [u32 * 16]
}
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
struct Context {
regs: Registers,
next: *Context,
@@ -70,6 +72,7 @@ struct BoxedRegion {
}
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
struct Task {
// Public fields
refcount: intptr_t, // 0
View
14 src/libcore/libc.rs
@@ -198,12 +198,14 @@ pub mod types {
// Standard types that are scalar but vary by OS and arch.
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
pub mod os {
pub mod common {
pub mod posix01 {}
}
#[cfg(target_arch = "x86")]
+ #[cfg(target_arch = "arm")]
pub mod arch {
pub mod c95 {
pub type c_char = i8;
@@ -797,6 +799,7 @@ pub mod consts {
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
pub mod os {
pub mod c95 {
pub const EXIT_FAILURE : int = 1;
@@ -1264,6 +1267,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub mod posix88 {
@@ -1283,7 +1287,8 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
- unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
+ #[cfg(target_os = "android")]
+ unsafe fn fstat(fildes: c_int, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
#[link_name = "fstat64"]
@@ -1294,6 +1299,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
+ #[cfg(target_os = "android")]
unsafe fn stat(path: *c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
@@ -1382,6 +1388,7 @@ pub mod funcs {
}
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub mod posix01 {
@@ -1394,6 +1401,7 @@ pub mod funcs {
pub extern mod stat_ {
#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
+ #[cfg(target_os = "android")]
unsafe fn lstat(path: *c_char, buf: *mut stat) -> c_int;
#[cfg(target_os = "macos")]
@@ -1410,6 +1418,7 @@ pub mod funcs {
unsafe fn fsync(fd: c_int) -> c_int;
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
unsafe fn fdatasync(fd: c_int) -> c_int;
unsafe fn setenv(name: *c_char, val: *c_char,
@@ -1442,6 +1451,7 @@ pub mod funcs {
#[cfg(target_os = "win32")]
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub mod posix08 {
@@ -1473,6 +1483,7 @@ pub mod funcs {
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
#[cfg(target_os = "win32")]
pub mod bsd44 {
}
@@ -1492,6 +1503,7 @@ pub mod funcs {
}
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
pub mod extra {
}
View
14 src/libcore/os.rs
@@ -325,6 +325,7 @@ pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
}
#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
unsafe {
use libc::funcs::posix01::unistd::*;
@@ -449,6 +450,7 @@ pub fn self_exe_path() -> Option<Path> {
}
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
fn load_self() -> Option<~str> {
unsafe {
use libc::funcs::posix01::unistd::readlink;
@@ -876,6 +878,7 @@ pub fn real_args() -> ~[~str] {
}
#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
#[cfg(target_os = "freebsd")]
pub fn real_args() -> ~[~str] {
unsafe {
@@ -976,7 +979,6 @@ pub mod consts {
pub const FAMILY: &str = "windows";
}
-
#[cfg(target_os = "macos")]
use os::consts::macos::*;
@@ -986,6 +988,9 @@ pub mod consts {
#[cfg(target_os = "linux")]
use os::consts::linux::*;
+ #[cfg(target_os = "android")]
+ use os::consts::android::*;
+
#[cfg(target_os = "win32")]
use os::consts::win32::*;
@@ -1010,6 +1015,13 @@ pub mod consts {
pub const EXE_SUFFIX: &str = "";
}
+ pub mod android {
+ pub const SYSNAME: &str = "android";
+ pub const DLL_PREFIX: &str = "lib";
+ pub const DLL_SUFFIX: &str = ".so";
+ pub const EXE_SUFFIX: &str = "";
+ }
+
pub mod win32 {
pub const SYSNAME: &str = "win32";
pub const DLL_PREFIX: &str = "";
View
2  src/libcore/path.rs
@@ -89,8 +89,10 @@ pub pure fn Path(s: &str) -> Path {
}
#[cfg(target_os = "linux")]
+#[cfg(target_os = "android")]
mod stat {
#[cfg(target_arch = "x86")]
+ #[cfg(target_arch = "arm")]
pub mod arch {
use libc;
View
2  src/libcore/run.rs
@@ -405,6 +405,7 @@ pub fn waitpid(pid: pid_t) -> int {
#[cfg(unix)]
fn waitpid_os(pid: pid_t) -> int {
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
fn WIFEXITED(status: i32) -> bool {
(status & 0xffi32) == 0i32
}
@@ -416,6 +417,7 @@ pub fn waitpid(pid: pid_t) -> int {
}
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
fn WEXITSTATUS(status: i32) -> i32 {
(status >> 8i32) & 0xffi32
}
View
85 src/librustc/back/arm.rs
@@ -0,0 +1,85 @@
+// 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 driver::session;
+use session::sess_os_to_meta_os;
+use metadata::loader::meta_section_name;
+
+fn get_target_strs(target_os: session::os) -> target_strs::t {
+ return {
+ module_asm: ~"",
+
+ meta_sect_name: meta_section_name(sess_os_to_meta_os(target_os)),
+
+ data_layout: match target_os {
+ session::os_macos => {
+ ~"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"
+ }
+
+ session::os_win32 => {
+ ~"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"
+ }
+
+ session::os_linux => {
+ ~"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"
+ }
+
+ session::os_android => {
+ ~"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"
+ }
+
+ session::os_freebsd => {
+ ~"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"
+ }
+ },
+
+ target_triple: match target_os {
+ session::os_macos => ~"arm-apple-darwin",
+ session::os_win32 => ~"arm-pc-mingw32",
+ session::os_linux => ~"arm-unknown-linux",
+ session::os_android => ~"arm-unknown-android",
+ session::os_freebsd => ~"arm-unknown-freebsd"
+ },
+
+ cc_args: ~[~"-marm"]
+ };
+}
+
+
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
View
17 src/librustc/back/link.rs
@@ -30,7 +30,7 @@ use core::cmp;
use core::hash;
use core::io::{Writer, WriterUtil};
use core::libc::{c_int, c_uint, c_char};
-use core::os::consts::{macos, freebsd, linux, win32};
+use core::os::consts::{macos, freebsd, linux, android, win32};
use core::os;
use core::ptr;
use core::run;
@@ -43,7 +43,7 @@ use syntax::ast_map::{path, path_mod, path_name};
use syntax::attr;
use syntax::print::pprust;
-pub enum output_type {
+enum output_type {
output_type_none,
output_type_bitcode,
output_type_assembly,
@@ -712,6 +712,7 @@ fn output_dll_filename(os: session::os, lm: &link_meta) -> ~str {
session::os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
session::os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
session::os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
+ session::os_android => (android::DLL_PREFIX, android::DLL_SUFFIX),
session::os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
};
return str::from_slice(dll_prefix) + libname +
@@ -758,7 +759,10 @@ fn link_binary(sess: Session,
// For win32, there is no cc command,
// so we add a condition to make it use gcc.
let cc_prog: ~str =
- if sess.targ_cfg.os == session::os_win32 { ~"gcc" } else { ~"cc" };
+ if sess.targ_cfg.os == session::os_android {
+ ~"arm-linux-androideabi-g++"
+ } else if sess.targ_cfg.os == session::os_win32 { ~"gcc" }
+ else { ~"cc" };
// The invocations of cc share some flags across platforms
let mut cc_args =
@@ -831,6 +835,11 @@ fn link_binary(sess: Session,
// have to be explicit about linking to it. See #2510
cc_args.push(~"-lm");
}
+ else if sess.targ_cfg.os == session::os_android {
+ cc_args.push_all(~[~"-ldl", ~"-llog", ~"-lsupc++",
+ ~"-lgnustl_shared"]);
+ cc_args.push(~"-lm");
+ }
if sess.targ_cfg.os == session::os_freebsd {
cc_args.push_all(~[~"-pthread", ~"-lrt",
@@ -851,7 +860,9 @@ fn link_binary(sess: Session,
}
// Stack growth requires statically linking a __morestack function
+ if sess.targ_cfg.os != session::os_android {
cc_args.push(~"-lmorestack");
+ }
// FIXME (#2397): At some point we want to rpath our guesses as to where
// extern libraries might live, based on the addl_lib_search_paths
View
4 src/librustc/back/rpath.rs
@@ -130,7 +130,8 @@ fn get_rpath_relative_to_output(os: session::os,
// Mac doesn't appear to support $ORIGIN
let prefix = match os {
- session::os_linux | session::os_freebsd => "$ORIGIN",
+ session::os_android |session::os_linux | session::os_freebsd
+ => "$ORIGIN",
session::os_macos => "@executable_path",
session::os_win32 => util::unreachable()
};
@@ -331,6 +332,7 @@ mod test {
#[test]
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "andorid")]
fn test_rpath_relative() {
let o = session::os_linux;
let res = get_rpath_relative_to_output(o,
View
4 src/librustc/back/x86.rs
@@ -35,6 +35,9 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
session::os_linux => {
~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
}
+ session::os_android => {
+ ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
+ }
session::os_freebsd => {
~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"
@@ -45,6 +48,7 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
session::os_macos => ~"i686-apple-darwin",
session::os_win32 => ~"i686-pc-mingw32",
session::os_linux => ~"i686-unknown-linux-gnu",
+ session::os_android => ~"i686-unknown-android-gnu",
session::os_freebsd => ~"i686-unknown-freebsd"
},
View
6 src/librustc/back/x86_64.rs
@@ -39,6 +39,11 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
~"f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-"+
~"s0:64:64-f80:128:128-n8:16:32:64-S128"
}
+ session::os_android => {
+ ~"e-p:64:64:64-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:128:128-a0:0:64-"+
+ ~"s0:64:64-f80:128:128-n8:16:32:64-S128"
+ }
session::os_freebsd => {
~"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"+
@@ -51,6 +56,7 @@ fn get_target_strs(target_os: session::os) -> target_strs::t {
session::os_macos => ~"x86_64-apple-darwin",
session::os_win32 => ~"x86_64-pc-mingw32",
session::os_linux => ~"x86_64-unknown-linux-gnu",
+ session::os_android => ~"x86_64-unknown-android-gnu",
session::os_freebsd => ~"x86_64-unknown-freebsd",
},
View
17 src/librustc/driver/driver.rs
@@ -12,7 +12,7 @@
use core::prelude::*;
use back::link;
-use back::{x86, x86_64};
+use back::{arm, x86, x86_64};
use front;
use lib::llvm::llvm;
use metadata::{creader, cstore, filesearch};
@@ -74,9 +74,18 @@ fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
session::os_win32 => ~"msvcrt.dll",
session::os_macos => ~"libc.dylib",
session::os_linux => ~"libc.so.6",
+ session::os_android => ~"libc.so",
session::os_freebsd => ~"libc.so.7"
// _ { "libc.so" }
};
+ let tos = match sess.targ_cfg.os {
+ session::os_win32 => ~"win32",
+ session::os_macos => ~"macos",
+ session::os_linux => ~"linux",
+ session::os_android => ~"android",
+ session::os_freebsd => ~"freebsd"
+ // _ { "libc.so" }
+ };
let mk = attr::mk_name_value_item_str;
@@ -88,7 +97,7 @@ fn default_configuration(sess: Session, +argv0: ~str, input: input) ->
return ~[ // Target bindings.
attr::mk_word_item(str::from_slice(os::FAMILY)),
- mk(~"target_os", str::from_slice(os::SYSNAME)),
+ mk(~"target_os", tos),
mk(~"target_family", str::from_slice(os::FAMILY)),
mk(~"target_arch", arch),
mk(~"target_word_size", wordsz),
@@ -424,6 +433,8 @@ fn get_os(triple: ~str) -> Option<session::os> {
Some(session::os_macos)
} else if str::contains(triple, ~"linux") {
Some(session::os_linux)
+ } else if str::contains(triple, ~"android") {
+ Some(session::os_android)
} else if str::contains(triple, ~"freebsd") {
Some(session::os_freebsd)
} else { None }
@@ -463,7 +474,7 @@ fn build_target_config(sopts: @session::options,
let target_strs = match arch {
session::arch_x86 => x86::get_target_strs(os),
session::arch_x86_64 => x86_64::get_target_strs(os),
- session::arch_arm => x86::get_target_strs(os)
+ session::arch_arm => arm::get_target_strs(os)
};
let target_cfg: @session::config =
@{os: os, arch: arch, target_strs: target_strs, int_type: int_type,
View
3  src/librustc/driver/session.rs
@@ -29,7 +29,7 @@ use syntax::parse::parse_sess;
use syntax::{ast, codemap};
use syntax;
-enum os { os_win32, os_macos, os_linux, os_freebsd, }
+enum os { os_win32, os_macos, os_linux, os_android, os_freebsd, }
impl os : cmp::Eq {
pure fn eq(&self, other: &os) -> bool {
@@ -326,6 +326,7 @@ fn sess_os_to_meta_os(os: os) -> metadata::loader::os {
match os {
os_win32 => loader::os_win32,
os_linux => loader::os_linux,
+ os_android => loader::os_android,
os_macos => loader::os_macos,
os_freebsd => loader::os_freebsd
}
View
7 src/librustc/metadata/loader.rs
@@ -28,7 +28,7 @@ use core::cast;
use core::flate;
use core::io::WriterUtil;
use core::io;
-use core::os::consts::{macos, freebsd, linux, win32};
+use core::os::consts::{macos, freebsd, linux, android, win32};
use core::option;
use core::ptr;
use core::str;
@@ -36,7 +36,7 @@ use core::uint;
use core::vec;
export os;
-export os_macos, os_win32, os_linux, os_freebsd;
+export os_macos, os_win32, os_linux, os_freebsd, os_android;
export ctxt;
export load_library_crate;
export list_file_metadata;
@@ -49,6 +49,7 @@ enum os {
os_macos,
os_win32,
os_linux,
+ os_android,
os_freebsd
}
@@ -86,6 +87,7 @@ fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} {
os_win32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
os_macos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
os_linux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
+ os_android => (android::DLL_PREFIX, android::DLL_SUFFIX),
os_freebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
};
return {
@@ -251,6 +253,7 @@ fn meta_section_name(os: os) -> ~str {
os_macos => ~"__DATA,__note.rustc",
os_win32 => ~".note.rustc",
os_linux => ~".note.rustc",
+ os_android => ~".note.rustc",
os_freebsd => ~".note.rustc"
}
}
View
27 src/librustc/middle/trans/base.rs
@@ -2152,7 +2152,9 @@ fn register_fn_fuller(ccx: @crate_ctxt,
let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
ccx.item_symbols.insert(node_id, ps);
- let is_main = is_main_name(path) && !ccx.sess.building_library;
+ let is_main = is_main_name(path) && (!ccx.sess.building_library ||
+ (ccx.sess.building_library &&
+ ccx.sess.targ_cfg.os == session::os_android));
if is_main { create_main_wrapper(ccx, sp, llfn); }
llfn
}
@@ -2202,7 +2204,12 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) {
#[cfg(unix)]
fn main_name() -> ~str { return ~"main"; }
let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
- let llfn = decl_cdecl_fn(ccx.llmod, main_name(), llfty);
+
+ let llfn = if ccx.sess.building_library {
+ decl_cdecl_fn(ccx.llmod, ~"amain", llfty)
+ } else {
+ decl_cdecl_fn(ccx.llmod, main_name(), llfty)
+ };
let llbb = str::as_c_str(~"top", |buf| {
unsafe {
llvm::LLVMAppendBasicBlock(llfn, buf)
@@ -2217,14 +2224,16 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) {
val_ty(crate_map)], ccx.int_type);
let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
- let args = unsafe {
- ~[
- rust_main,
- llvm::LLVMGetParam(llfn, 0 as c_uint),
- llvm::LLVMGetParam(llfn, 1 as c_uint),
- crate_map
- ]
+ let args = if ccx.sess.building_library unsafe {
+ ~[rust_main,
+ llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
+ llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
+ crate_map]
+ } else unsafe {
+ ~[rust_main, llvm::LLVMGetParam(llfn, 0 as c_uint),
+ llvm::LLVMGetParam(llfn, 1 as c_uint), crate_map]
};
+
let result = unsafe {
llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
args.len() as c_uint, noname())
View
11 src/librustc/middle/trans/foreign.rs
@@ -15,6 +15,7 @@ use core::prelude::*;
use back::{link, abi};
use driver::session::arch_x86_64;
+use driver::session::arch_arm;
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
use lib::llvm::{Struct, Array, ModuleRef, CallConv, Attribute};
use lib::llvm::{StructRetAttribute, ByValAttribute};
@@ -494,6 +495,8 @@ fn c_stack_tys(ccx: @crate_ctxt,
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
let x86_64 = if ccx.sess.targ_cfg.arch == arch_x86_64 {
option::Some(x86_64_tys(llargtys, llretty, ret_def))
+ } else if ccx.sess.targ_cfg.arch == arch_arm {
+ option::Some(x86_64_tys(llargtys, llretty, ret_def))
} else {
option::None
};
@@ -1491,6 +1494,14 @@ fn register_foreign_fn(ccx: @crate_ctxt,
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
t, lib::llvm::CCallConv, fnty)
}
+ } else if ccx.sess.targ_cfg.arch == arch_arm {
+ let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
+ let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
+ do decl_x86_64_fn(x86_64) |fnty| {
+ register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
+ t, lib::llvm::CCallConv, fnty)
+ }
+
} else {
let llfty = T_fn(llargtys, llretty);
register_fn_fuller(ccx, sp, path, node_id, attrs,
View
2  src/librustc/rustc.rc
@@ -162,6 +162,8 @@ mod back {
#[legacy_exports]
mod upcall;
#[legacy_exports]
+ mod arm;
+ #[legacy_exports]
mod x86;
#[legacy_exports]
mod x86_64;
View
2  src/libstd/net_tcp.rs
@@ -1291,6 +1291,7 @@ pub mod test {
#[cfg(target_os="win32")]
#[cfg(target_os="darwin")]
#[cfg(target_os="linux")]
+ #[cfg(target_os="android")]
pub mod tcp_ipv4_server_and_client_test {
#[cfg(target_arch="x86_64")]
pub mod impl64 {
@@ -1329,6 +1330,7 @@ pub mod test {
}
}
#[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
pub mod impl32 {
use net::tcp::test::*;
View
15 src/libstd/uv_ll.rs
@@ -109,6 +109,7 @@ pub type uv_tcp_t_32bit_unix_riders = {
a29: *u8
};
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
pub type uv_tcp_t_32bit_unix_riders = {
a29: *u8, a30: *u8, a31: *u8,
a32: *u8, a33: *u8, a34: *u8,
@@ -165,6 +166,7 @@ pub type uv_write_t_32bit_unix_riders = {
a13: *u8
};
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
pub type uv_write_t_32bit_unix_riders = {
a13: *u8, a14: *u8
};
@@ -192,6 +194,7 @@ pub type uv_async_t_32bit_unix_riders = {
a10: *u8
};
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
pub type uv_async_t_32bit_unix_riders = {
a10: *u8, a11: *u8, a12: *u8, a13: *u8
};
@@ -220,6 +223,7 @@ pub type uv_timer_t_32bit_unix_riders = {
a10: *u8, a11: *u8
};
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
pub type uv_timer_t_32bit_unix_riders = {
a10: *u8, a11: *u8, a12: *u8, a13: *u8,
a14: *u8, a15: *u8, a16: *u8
@@ -249,6 +253,7 @@ pub type sockaddr_in6 = {
a2: *u8, a3: *u8
};
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
pub type sockaddr_in6 = {
a0: *u8, a1: *u8,
a2: *u8, a3: *u8,
@@ -267,6 +272,7 @@ pub mod addr_in_impl {
a2: *u8, a3: *u8
};
#[cfg(target_arch="x86")]
+#[cfg(target_arch="arm")]
pub type addr_in = {
a0: *u8, a1: *u8,
a2: *u8, a3: *u8,
@@ -285,6 +291,7 @@ pub mod addr_in_impl {
// unix size: 48, 32bit: 32
pub type addrinfo = addrinfo_impl::addrinfo;
#[cfg(target_os="linux")]
+#[cfg(target_os="android")]
pub mod addrinfo_impl {
#[cfg(target_arch="x86_64")]
pub type addrinfo = {
@@ -292,6 +299,7 @@ pub mod addrinfo_impl {
a04: *u8, a05: *u8
};
#[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
pub type addrinfo = {
a00: *u8, a01: *u8, a02: *u8, a03: *u8,
a04: *u8, a05: *u8, a06: *u8, a07: *u8
@@ -328,6 +336,7 @@ pub mod uv_ll_struct_stubgen {
pub fn gen_stub_uv_tcp_t() -> uv_tcp_t {
return gen_stub_os();
#[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
pub fn gen_stub_os() -> uv_tcp_t {
@@ -358,6 +367,7 @@ pub mod uv_ll_struct_stubgen {
};
}
#[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_tcp_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(),
@@ -443,6 +453,7 @@ pub mod uv_ll_struct_stubgen {
};
}
#[cfg(target_arch = "x86")]
+ #[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_async_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(),
@@ -492,6 +503,7 @@ pub mod uv_ll_struct_stubgen {
};
}
#[cfg(target_arch = "x86")]
+ #[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_timer_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(),
@@ -541,6 +553,7 @@ pub mod uv_ll_struct_stubgen {
};
}
#[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
pub fn gen_stub_arch() -> uv_write_t {
return { fields: { loop_handle: ptr::null(), type_: 0u32,
close_cb: ptr::null(),
@@ -1571,6 +1584,7 @@ pub mod test {
#[cfg(target_os="win32")]
#[cfg(target_os="darwin")]
#[cfg(target_os="linux")]
+ #[cfg(target_os="android")]
pub mod tcp_and_server_client_test {
#[cfg(target_arch="x86_64")]
pub mod impl64 {
@@ -1581,6 +1595,7 @@ pub mod test {
}
}
#[cfg(target_arch="x86")]
+ #[cfg(target_arch="arm")]
pub mod impl32 {
use uv_ll::test::*;
#[test]
View
47 src/rt/arch/arm/_context.S
@@ -0,0 +1,47 @@
+.text
+.code 32
+.arm
+.align
+
+
+.globl swap_registers
+swap_registers:
+ str r0, [r0, #0]
+ str r3, [r0, #12]
+ str r4, [r0, #16]
+ str r5, [r0, #20]
+ str r6, [r0, #24]
+ str r7, [r0, #28]
+ str r8, [r0, #32]
+ str r9, [r0, #36]
+ str r10, [r0, #40]
+ str r11, [r0, #44]
+ str r12, [r0, #48]
+ str sp, [r0, #52]
+ str lr, [r0, #56]
+
+ mrs r2, cpsr
+ str r2, [r0, #64]
+
+
+ ldr r0, [r1, #0]
+ ldr r3, [r1, #12]
+ ldr r4, [r1, #16]
+ ldr r5, [r1, #20]
+ ldr r6, [r1, #24]
+ ldr r7, [r1, #28]
+ ldr r8, [r1, #32]
+ ldr r9, [r1, #36]
+ ldr r10, [r1, #40]
+ ldr r11, [r1, #44]
+ ldr r12, [r1, #48]
+
+ ldr sp, [r1, #52]
+ ldr lr, [r1, #56]
+
+ ldr r2, [r1, #64]
+ msr cpsr_cxsf, r2
+
+ mov pc, lr
+
+
View
27 src/rt/arch/arm/ccall.S
@@ -0,0 +1,27 @@
+.text
+.code 32
+.arm
+.align
+
+.globl __morestack
+.hidden __morestack
+__morestack:
+ mov r3, sp
+ mov sp, r2
+
+ str r3, [sp]
+ str lr, [sp, #-4]
+
+ sub sp, #8
+
+ blx r1
+
+ add sp, #8
+
+ ldr lr, [sp, #-4]
+ ldr r3, [sp]
+
+ mov sp, r3
+ mov pc, lr
+
+
View
36 src/rt/arch/arm/context.cpp
@@ -0,0 +1,36 @@
+
+#include "context.h"
+#include "../../rust_globals.h"
+
+extern "C" void CDECL swap_registers(registers_t *oregs,
+ registers_t *regs)
+asm ("swap_registers");
+
+context::context()
+{
+ assert((void*)&regs == (void*)this);
+ memset(&regs, 0, sizeof(regs));
+}
+
+void context::swap(context &out)
+{
+ swap_registers(&out.regs, &regs);
+}
+
+void context::call(void *f, void *arg, void *stack)
+{
+ // Get the current context, which we will then modify to call the
+ // given function.
+ swap(*this);
+
+ // set up the stack
+ uint32_t *sp = ( uint32_t *)stack;
+ //sp = align_down(sp);
+ // The final return address. 0 indicates the bottom of the stack
+ *--sp = 0;
+
+ regs.data[0] = ( uint32_t )arg; // r0
+ regs.data[13] = ( uint32_t )sp; //#52 sp, r13
+ regs.data[14] = ( uint32_t )f; //#60 pc, r15 --> lr,
+ // Last base pointer on the stack should be 0
+}
View
43 src/rt/arch/arm/context.h
@@ -0,0 +1,43 @@
+// -*- mode: c++ -*-
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+#include <cstdlib>
+#include <inttypes.h>
+#include <stdint.h>
+//#include <xmmintrin.h>
+
+#include "vg/memcheck.h"
+
+template<typename T>
+T align_down(T sp)
+{
+ // There is no platform we care about that needs more than a
+ // 16-byte alignment.
+ return (T)((uint32_t)sp & ~(16 - 1));
+}
+
+// The struct in which we store the saved data. This is mostly the
+// volatile registers and instruction pointer, but it also includes
+// RCX/RDI which are used to pass arguments. The indices for each
+// register are found in "regs.h". Note that the alignment must be
+// 16 bytes so that SSE instructions can be used.
+#include "regs.h"
+struct registers_t {
+ uint32_t data[RUSTRT_MAX];
+} __attribute__((aligned(16)));
+
+class context {
+public:
+ registers_t regs;
+
+ context();
+
+ context *next;
+
+ void swap(context &out);
+ void call(void *f, void *arg, void *sp);
+};
+
+#endif
View
15 src/rt/arch/arm/gpr.cpp
@@ -0,0 +1,15 @@
+#include "gpr.h"
+
+#define LOAD(rn) do { \
+ uintptr_t tmp; \
+ asm("mov %%" #rn ",%0" : "=r" (tmp) :); \
+ this->rn = tmp; \
+} while (0)
+
+void rust_gpr::load() {
+ LOAD(r0); LOAD(r1); LOAD(r2); LOAD(r3);
+ LOAD(r4); LOAD(r5); LOAD(r6); LOAD(r7);
+ LOAD(r8); LOAD(r9); LOAD(r10); LOAD(r11);
+ LOAD(r12); LOAD(r13); LOAD(r14); LOAD(r15);
+}
+
View
23 src/rt/arch/arm/gpr.h
@@ -0,0 +1,23 @@
+// General-purpose registers. This structure is used during stack crawling.
+
+#ifndef GPR_H
+#define GPR_H
+
+#include "rust_gpr_base.h"
+
+class rust_gpr : public rust_gpr_base {
+public:
+ uintptr_t r0, r1, r2, r3, r4, r5, r6, r7;
+ uintptr_t r8, r9, r10, r11, r12, r13, r14, r15;
+
+ inline uintptr_t get_fp() { return r11; }
+ inline uintptr_t get_ip() { return r12; }
+
+ inline void set_fp(uintptr_t new_fp) { r11 = new_fp; }
+ inline void set_ip(uintptr_t new_ip) { r12 = new_ip; }
+
+ void load();
+};
+
+#endif
+
View
61 src/rt/arch/arm/record_sp.S
@@ -0,0 +1,61 @@
+.text
+.code 32
+.arm
+.align
+
+
+.globl record_sp_limit
+.globl get_sp_limit
+.globl get_sp
+
+record_sp_limit:
+ mov r3, r0
+ ldr r0, =my_cpu
+ mov r1, #0
+ mov r2, #0
+ stmfd sp!, {r3, r7}
+ ldr r7, =345
+ swi #0
+ ldmfd sp!, {r3, r7}
+ movs r0, r0
+ movmi r0, #0
+
+ ldr r1, =my_array
+ str r3, [r1, r0]
+ mov pc, lr
+
+
+get_sp_limit:
+ ldr r0, =my_cpu
+ mov r1, #0
+ mov r2, #0
+ stmfd sp!, {r4, r7}
+ ldr r7, =345
+ swi #0
+ ldmfd sp!, {r4, r7}
+ movs r0, r0
+ movmi r0, #0
+ mov r3, r0
+
+ ldr r1, =my_array
+ ldr r0, [r1, r3]
+ mov pc, lr
+
+
+get_sp:
+ mov r0, sp
+ mov pc, lr
+
+.data
+my_cpu: .long 0
+.global my_array
+my_array:
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+ .long 0
+.end
View
21 src/rt/arch/arm/regs.h
@@ -0,0 +1,21 @@
+#define RUSTRT_RBX 0
+#define RUSTRT_RSP 1
+#define RUSTRT_RBP 2
+// RCX on Windows, RDI elsewhere
+#define RUSTRT_ARG0 3
+#define RUSTRT_R12 4
+#define RUSTRT_R13 5
+#define RUSTRT_R14 6
+#define RUSTRT_R15 7
+#define RUSTRT_IP 8
+
+#define RUSTRT_MAX 32
+
+// ARG0 is the register in which the first argument goes.
+// Naturally this depends on your operating system.
+# define RUSTRT_ARG0_S r0
+# define RUSTRT_ARG1_S r1
+# define RUSTRT_ARG2_S r2
+# define RUSTRT_ARG3_S r3
+
+
View
61 src/rt/rust_android_dummy.cpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "rust_android_dummy.h"
+#include <math.h>
+
+#ifdef __ANDROID__
+
+int backtrace(void **array, int size) { return 0; }
+
+char **backtrace_symbols(void *const *array, int size) { return 0; }
+
+void backtrace_symbols_fd (void *const *array, int size, int fd) {}
+
+
+extern "C" float log2f(float f)
+{
+ return logf( f ) / logf( 2 );
+}
+
+extern "C" double log2( double n )
+{
+ return log( n ) / log( 2 );
+}
+
+extern "C" void telldir()
+{
+}
+
+extern "C" void seekdir()
+{
+}
+
+extern "C" void mkfifo()
+{
+}
+
+extern "C" void abs()
+{
+}
+
+extern "C" void labs()
+{
+}
+
+extern "C" void rand()
+{
+}
+
+extern "C" void srand()
+{
+}
+
+extern "C" void atof()
+{
+}
+extern "C" void tgammaf()
+{
+}
+#endif
View
5 src/rt/rust_android_dummy.h
@@ -0,0 +1,5 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "execinfo.h"
View
21 src/rt/rust_builtin.cpp
@@ -33,6 +33,27 @@
extern char **environ;
#endif
+#ifdef __ANDROID__
+time_t
+timegm(struct tm *tm)
+{
+ time_t ret;
+ char *tz;
+
+ tz = getenv("TZ");
+ setenv("TZ", "", 1);
+ tzset();
+ ret = mktime(tm);
+ if (tz)
+ setenv("TZ", tz, 1);
+ else
+ unsetenv("TZ");
+ tzset();
+ return ret;
+}
+#endif
+
+
extern "C" CDECL rust_str*
last_os_error() {
rust_task *task = rust_get_current_task();
View
1  src/rt/rust_sched_loop.cpp
@@ -28,6 +28,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) :
id(id),
should_exit(false),
cached_c_stack(NULL),
+ extra_c_stack(NULL),
dead_task(NULL),
killed(killed),
pump_signal(NULL),
View
3  src/rt/rust_task.h
@@ -165,6 +165,9 @@
#define RED_ZONE_SIZE RZ_BSD_64
#endif
#endif
+#ifdef __ANDROID__
+#define RED_ZONE_SIZE RZ_MAC_32
+#endif
struct rust_box;
View
12 src/rustllvm/RustWrapper.cpp
@@ -91,6 +91,12 @@ void LLVMInitializeX86TargetMC();
void LLVMInitializeX86AsmPrinter();
void LLVMInitializeX86AsmParser();
+
+void LLVMInitializeARMTargetInfo();
+void LLVMInitializeARMTarget();
+void LLVMInitializeARMTargetMC();
+void LLVMInitializeARMAsmPrinter();
+void LLVMInitializeARMAsmParser();
// Only initialize the platforms supported by Rust here,
// because using --llvm-root will have multiple platforms
// that rustllvm doesn't actually link to and it's pointless to put target info
@@ -102,6 +108,12 @@ void LLVMRustInitializeTargets() {
LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmPrinter();
LLVMInitializeX86AsmParser();
+
+ LLVMInitializeARMTargetInfo();
+ LLVMInitializeARMTarget();
+ LLVMInitializeARMTargetMC();
+ LLVMInitializeARMAsmPrinter();
+ LLVMInitializeARMAsmParser();
}
// Custom memory manager for MCJITting. It needs special features
View
14 src/rustllvm/rustllvm.def.in
@@ -383,19 +383,19 @@ LLVMInitializeInstCombine
LLVMInitializeScalarOpts
LLVMInitializeTarget
LLVMInitializeTransformUtils
+LLVMInitializeARMAsmLexer
LLVMInitializeX86AsmLexer
-LLVMInitializeX86AsmLexer
-LLVMInitializeX86AsmParser
+LLVMInitializeARMAsmParser
LLVMInitializeX86AsmParser
+LLVMInitializeARMAsmPrinter
LLVMInitializeX86AsmPrinter
-LLVMInitializeX86AsmPrinter
-LLVMInitializeX86Disassembler
+LLVMInitializeARMDisassembler
LLVMInitializeX86Disassembler
+LLVMInitializeARMTarget
LLVMInitializeX86Target
-LLVMInitializeX86Target
-LLVMInitializeX86TargetMC
+LLVMInitializeARMTargetMC
LLVMInitializeX86TargetMC
-LLVMInitializeX86TargetInfo
+LLVMInitializeARMTargetInfo
LLVMInitializeX86TargetInfo
LLVMInsertBasicBlock
LLVMInsertBasicBlockInContext
Please sign in to comment.
Something went wrong with that request. Please try again.