From 987f824f233faee4aed39dac92a1b442d42965cc Mon Sep 17 00:00:00 2001 From: kyeongwoon Date: Fri, 30 Nov 2012 09:21:49 +0900 Subject: [PATCH] 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 --- Makefile.in | 2 +- configure | 2 +- src/libcore/cleanup.rs | 3 + src/libcore/libc.rs | 14 ++++- src/libcore/os.rs | 14 ++++- src/libcore/path.rs | 2 + src/libcore/run.rs | 2 + src/librustc/back/arm.rs | 85 ++++++++++++++++++++++++++++ src/librustc/back/link.rs | 17 +++++- src/librustc/back/rpath.rs | 4 +- src/librustc/back/x86.rs | 4 ++ src/librustc/back/x86_64.rs | 6 ++ src/librustc/driver/driver.rs | 17 +++++- src/librustc/driver/session.rs | 3 +- src/librustc/metadata/loader.rs | 7 ++- src/librustc/middle/trans/base.rs | 27 ++++++--- src/librustc/middle/trans/foreign.rs | 11 ++++ src/librustc/rustc.rc | 2 + src/libstd/net_tcp.rs | 2 + src/libstd/uv_ll.rs | 15 +++++ src/rt/arch/arm/_context.S | 47 +++++++++++++++ src/rt/arch/arm/ccall.S | 27 +++++++++ src/rt/arch/arm/context.cpp | 36 ++++++++++++ src/rt/arch/arm/context.h | 43 ++++++++++++++ src/rt/arch/arm/gpr.cpp | 15 +++++ src/rt/arch/arm/gpr.h | 23 ++++++++ src/rt/arch/arm/record_sp.S | 61 ++++++++++++++++++++ src/rt/arch/arm/regs.h | 21 +++++++ src/rt/rust_android_dummy.cpp | 61 ++++++++++++++++++++ src/rt/rust_android_dummy.h | 5 ++ src/rt/rust_builtin.cpp | 21 +++++++ src/rt/rust_sched_loop.cpp | 1 + src/rt/rust_task.h | 3 + src/rustllvm/RustWrapper.cpp | 12 ++++ src/rustllvm/rustllvm.def.in | 14 ++--- 35 files changed, 599 insertions(+), 30 deletions(-) create mode 100644 src/librustc/back/arm.rs create mode 100644 src/rt/arch/arm/_context.S create mode 100644 src/rt/arch/arm/ccall.S create mode 100644 src/rt/arch/arm/context.cpp create mode 100644 src/rt/arch/arm/context.h create mode 100644 src/rt/arch/arm/gpr.cpp create mode 100644 src/rt/arch/arm/gpr.h create mode 100644 src/rt/arch/arm/record_sp.S create mode 100644 src/rt/arch/arm/regs.h create mode 100644 src/rt/rust_android_dummy.cpp create mode 100644 src/rt/rust_android_dummy.h diff --git a/Makefile.in b/Makefile.in index 963f455fe8a..e476ac1dba2 100644 --- a/Makefile.in +++ b/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 diff --git a/configure b/configure index acf27a218a6..f466f0fa3d7 100755 --- a/configure +++ b/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" diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index c8b96b9b23b..656f672479e 100644 --- a/src/libcore/cleanup.rs +++ b/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 diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index cc9e4d1c5a9..ecd48fe16bc 100644 --- a/src/libcore/libc.rs +++ b/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 { } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index f602b230f45..ff3253a8223 100644 --- a/src/libcore/os.rs +++ b/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 { } #[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 = ""; diff --git a/src/libcore/path.rs b/src/libcore/path.rs index cf1188b1f35..7f5f334ac1f 100644 --- a/src/libcore/path.rs +++ b/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; diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 435feb16023..54bce77d308 100644 --- a/src/libcore/run.rs +++ b/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 } diff --git a/src/librustc/back/arm.rs b/src/librustc/back/arm.rs new file mode 100644 index 00000000000..2c4e0af0f2d --- /dev/null +++ b/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 or the MIT license +// , 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: +// diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 0512994f994..e49d9da3355 100644 --- a/src/librustc/back/link.rs +++ b/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 diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs index 8378270bee4..005a5404b37 100644 --- a/src/librustc/back/rpath.rs +++ b/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, diff --git a/src/librustc/back/x86.rs b/src/librustc/back/x86.rs index 205867feb3d..7ac2bb73ebb 100644 --- a/src/librustc/back/x86.rs +++ b/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" }, diff --git a/src/librustc/back/x86_64.rs b/src/librustc/back/x86_64.rs index 929634e5bd3..aaf97587813 100644 --- a/src/librustc/back/x86_64.rs +++ b/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", }, diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 1e1e1d2b325..030856539a5 100644 --- a/src/librustc/driver/driver.rs +++ b/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 { 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, diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index ee34570203b..b2b6cb25dbb 100644 --- a/src/librustc/driver/session.rs +++ b/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 } diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 535f45ae839..58c9a1b90f2 100644 --- a/src/librustc/metadata/loader.rs +++ b/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" } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index a8b0da47e9a..165d9b60a61 100644 --- a/src/librustc/middle/trans/base.rs +++ b/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()) diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 06383cfa228..4c373e0d217 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/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, diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 60780df5287..56a22899193 100644 --- a/src/librustc/rustc.rc +++ b/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; diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 9e0dc0ff12e..847962c1773 100644 --- a/src/libstd/net_tcp.rs +++ b/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::*; diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index 778daf131c4..eee3d60a66d 100644 --- a/src/libstd/uv_ll.rs +++ b/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] diff --git a/src/rt/arch/arm/_context.S b/src/rt/arch/arm/_context.S new file mode 100644 index 00000000000..8d370c2d64e --- /dev/null +++ b/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 + + diff --git a/src/rt/arch/arm/ccall.S b/src/rt/arch/arm/ccall.S new file mode 100644 index 00000000000..4b89cc994a7 --- /dev/null +++ b/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 + + diff --git a/src/rt/arch/arm/context.cpp b/src/rt/arch/arm/context.cpp new file mode 100644 index 00000000000..dbf06a532a8 --- /dev/null +++ b/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*)®s == (void*)this); + memset(®s, 0, sizeof(regs)); +} + +void context::swap(context &out) +{ + swap_registers(&out.regs, ®s); +} + +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 +} diff --git a/src/rt/arch/arm/context.h b/src/rt/arch/arm/context.h new file mode 100644 index 00000000000..6c7db766d6a --- /dev/null +++ b/src/rt/arch/arm/context.h @@ -0,0 +1,43 @@ +// -*- mode: c++ -*- + +#ifndef CONTEXT_H +#define CONTEXT_H + +#include +#include +#include +//#include + +#include "vg/memcheck.h" + +template +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 diff --git a/src/rt/arch/arm/gpr.cpp b/src/rt/arch/arm/gpr.cpp new file mode 100644 index 00000000000..32a68d0732a --- /dev/null +++ b/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); +} + diff --git a/src/rt/arch/arm/gpr.h b/src/rt/arch/arm/gpr.h new file mode 100644 index 00000000000..472c8a05e35 --- /dev/null +++ b/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 + diff --git a/src/rt/arch/arm/record_sp.S b/src/rt/arch/arm/record_sp.S new file mode 100644 index 00000000000..193104d53b1 --- /dev/null +++ b/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 diff --git a/src/rt/arch/arm/regs.h b/src/rt/arch/arm/regs.h new file mode 100644 index 00000000000..a49fcab1184 --- /dev/null +++ b/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 + + diff --git a/src/rt/rust_android_dummy.cpp b/src/rt/rust_android_dummy.cpp new file mode 100644 index 00000000000..76aa51723ef --- /dev/null +++ b/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 + +#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 diff --git a/src/rt/rust_android_dummy.h b/src/rt/rust_android_dummy.h new file mode 100644 index 00000000000..2e8b6f2c766 --- /dev/null +++ b/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" diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index b16006e1f91..0919ccf7f0e 100644 --- a/src/rt/rust_builtin.cpp +++ b/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(); diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp index e56ce6dd263..5ddfd88d4b4 100644 --- a/src/rt/rust_sched_loop.cpp +++ b/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), diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 27694becdfb..20c9a48f1dd 100644 --- a/src/rt/rust_task.h +++ b/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; diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index b01294062a6..3c38f3c6215 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/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 diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 44636f4f36b..d3cbc490ada 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/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 +LLVMInitializeARMTargetMC LLVMInitializeX86TargetMC -LLVMInitializeX86TargetMC -LLVMInitializeX86TargetInfo +LLVMInitializeARMTargetInfo LLVMInitializeX86TargetInfo LLVMInsertBasicBlock LLVMInsertBasicBlockInContext