Permalink
Checking mergeability…
Don’t worry, you can still create the pull request.
Comparing changes
Open a pull request
- 4 commits
- 36 files changed
- 0 commit comments
- 1 contributor
Unified
Split
Showing
with
1,113 additions
and 723 deletions.
- +11 −1 src/librustc/lib/llvm.rs
- +12 −0 src/librustc/metadata/encoder.rs
- +4 −0 src/librustc/middle/lint.rs
- +23 −0 src/librustc/middle/resolve.rs
- +8 −112 src/librustc/middle/trans/base.rs
- +43 −2 src/librustc/middle/trans/foreign.rs
- +1 −111 src/librustc/middle/trans/intrinsic.rs
- +1 −34 src/librustc/middle/trans/type_use.rs
- +0 −102 src/librustc/middle/typeck/check/mod.rs
- +22 −0 src/librustc/middle/typeck/collect.rs
- +2 −0 src/librustdoc/extract.rs
- +32 −11 src/libstd/num/f32.rs
- +32 −11 src/libstd/num/f64.rs
- +9 −15 src/libstd/num/i16.rs
- +9 −15 src/libstd/num/i32.rs
- +9 −15 src/libstd/num/i64.rs
- +9 −15 src/libstd/num/i8.rs
- +12 −24 src/libstd/num/int.rs
- +6 −12 src/libstd/num/u16.rs
- +6 −12 src/libstd/num/u32.rs
- +6 −12 src/libstd/num/u64.rs
- +6 −12 src/libstd/num/u8.rs
- +12 −24 src/libstd/num/uint.rs
- +648 −111 src/libstd/unstable/intrinsics.rs
- +2 −0 src/libsyntax/ast.rs
- +2 −0 src/libsyntax/ext/base.rs
- +97 −0 src/libsyntax/ext/ir_module.rs
- +11 −0 src/libsyntax/fold.rs
- +1 −1 src/libsyntax/parse/parser.rs
- +15 −0 src/libsyntax/print/pprust.rs
- +2 −0 src/libsyntax/syntax.rs
- +4 −0 src/libsyntax/visit.rs
- +48 −0 src/rustllvm/RustWrapper.cpp
- +2 −0 src/rustllvm/rustllvm.def.in
- +1 −25 src/test/run-pass/intrinsics-integer.rs
- +5 −46 src/test/run-pass/intrinsics-math.rs
| @@ -1859,6 +1859,16 @@ pub mod llvm { | |||
| #[fast_ffi] | |||
| pub fn LLVMRustStartMultithreading() -> bool; | |||
|
|
|||
| #[fast_ffi] | |||
| pub fn LLVMRustAddRawIR(M: ModuleRef, code: *c_char) -> bool; | |||
|
|
|||
| #[fast_ffi] | |||
| pub fn LLVMRustCreateIRFunction(M: ModuleRef, | |||
| f: TypeRef, | |||
| name: *c_char, | |||
| code: *c_char) | |||
| -> bool; | |||
|
|
|||
| #[fast_ffi] | |||
| pub fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char) -> TypeRef; | |||
|
|
|||
| @@ -2268,7 +2278,7 @@ impl TypeNames { | |||
| Label => ~"Label", | |||
| Vector => ~"Vector", | |||
| Metadata => ~"Metadata", | |||
| X86_MMX => ~"X86_MMAX", | |||
| X86_MMX => ~"X86_MAX", | |||
| Integer => { | |||
| fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int) | |||
| } | |||
| @@ -1226,6 +1226,9 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, | |||
|
|
|||
| ebml_w.start_tag(tag_items_data_item); | |||
| match nitem.node { | |||
| foreign_item_raw_ir(*) => { // TODO: Fix this shit | |||
| encode_def_id(ebml_w, local_def(nitem.id)); | |||
| } | |||
| foreign_item_fn(*) => { | |||
| encode_def_id(ebml_w, local_def(nitem.id)); | |||
| encode_family(ebml_w, purity_fn_family(impure_fn)); | |||
| @@ -1239,6 +1242,15 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, | |||
| } | |||
| encode_path(ecx, ebml_w, *path, ast_map::path_name(nitem.ident)); | |||
| } | |||
| foreign_item_ir_fn(*) => { // TODO: Fix this shit | |||
| encode_def_id(ebml_w, local_def(nitem.id)); | |||
| encode_family(ebml_w, purity_fn_family(impure_fn)); | |||
| encode_bounds_and_type(ebml_w, ecx, | |||
| &lookup_item_type(ecx.tcx,local_def(nitem.id))); | |||
| encode_name(ecx, ebml_w, nitem.ident); | |||
| (ecx.encode_inlined_item)(ecx, ebml_w, *path, ii_foreign(nitem)); | |||
| encode_path(ecx, ebml_w, *path, ast_map::path_name(nitem.ident)); | |||
| } | |||
| foreign_item_static(_, mutbl) => { | |||
| encode_def_id(ebml_w, local_def(nitem.id)); | |||
| if mutbl { | |||
| @@ -919,9 +919,13 @@ fn check_item_ctypes(cx: &Context, it: &ast::item) { | |||
| ast::item_foreign_mod(ref nmod) if !nmod.abis.is_intrinsic() => { | |||
| for ni in nmod.items.iter() { | |||
| match ni.node { | |||
| ast::foreign_item_raw_ir(_) => {} | |||
| ast::foreign_item_fn(ref decl, _) => { | |||
| check_foreign_fn(cx, decl); | |||
| } | |||
| ast::foreign_item_ir_fn(ref decl, _) => { | |||
| check_foreign_fn(cx, decl); | |||
| } | |||
| ast::foreign_item_static(ref t, _) => { check_ty(cx, t); } | |||
| } | |||
| } | |||
| @@ -1605,6 +1605,9 @@ impl Resolver { | |||
| foreign_item.span); | |||
|
|
|||
| match foreign_item.node { | |||
| foreign_item_raw_ir(*) => { | |||
| visit::walk_foreign_item(visitor, foreign_item, new_parent); | |||
| } | |||
| foreign_item_fn(_, ref generics) => { | |||
| let def = DefFn(local_def(foreign_item.id), unsafe_fn); | |||
| name_bindings.define_value(Public, def, foreign_item.span); | |||
| @@ -1616,6 +1619,14 @@ impl Resolver { | |||
| visit::walk_foreign_item(visitor, foreign_item, new_parent); | |||
| } | |||
| } | |||
| foreign_item_ir_fn(*) => { | |||
| let def = DefFn(local_def(foreign_item.id), unsafe_fn); | |||
| name_bindings.define_value(Public, def, foreign_item.span); | |||
|
|
|||
| do self.with_type_parameter_rib(NoTypeParameters) { | |||
| visit::walk_foreign_item(visitor, foreign_item, new_parent); | |||
| } | |||
| } | |||
| foreign_item_static(_, m) => { | |||
| let def = DefStatic(local_def(foreign_item.id), m); | |||
| name_bindings.define_value(Public, def, foreign_item.span); | |||
| @@ -3674,6 +3685,11 @@ impl Resolver { | |||
| do self.with_scope(Some(item.ident)) { | |||
| for foreign_item in foreign_module.items.iter() { | |||
| match foreign_item.node { | |||
| foreign_item_raw_ir(*) => { | |||
| visit::walk_foreign_item(visitor, | |||
| *foreign_item, | |||
| ()); | |||
| } | |||
| foreign_item_fn(_, ref generics) => { | |||
| self.with_type_parameter_rib( | |||
| HasTypeParameters( | |||
| @@ -3683,6 +3699,13 @@ impl Resolver { | |||
| *foreign_item, | |||
| ())); | |||
| } | |||
| foreign_item_ir_fn(*) => { | |||
| self.with_type_parameter_rib( | |||
| NoTypeParameters, | |||
| || visit::walk_foreign_item(visitor, | |||
| *foreign_item, | |||
| ())); | |||
| } | |||
| foreign_item_static(*) => { | |||
| visit::walk_foreign_item(visitor, | |||
| *foreign_item, | |||
| @@ -2629,7 +2629,10 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef { | |||
| exprt = true; | |||
|
|
|||
| match ni.node { | |||
| ast::foreign_item_fn(*) => { | |||
| ast::foreign_item_raw_ir(*) => { | |||
| ccx.tcx.sess.bug("Raw IR should not be registered") | |||
| } | |||
| ast::foreign_item_fn(*) | ast::foreign_item_ir_fn(*) => { | |||
| let path = vec::append((*pth).clone(), [path_name(ni.ident)]); | |||
| foreign::register_foreign_item_fn(ccx, abis, &path, ni) | |||
| } | |||
| @@ -2743,8 +2746,11 @@ macro_rules! ifn ( | |||
| ) | |||
|
|
|||
| pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { | |||
| let i8p = Type::i8p(); | |||
| let mut intrinsics = HashMap::new(); | |||
| let i8p = Type::i8p(); | |||
|
|
|||
| ifn!(intrinsics, "llvm.trap", [], Type::void()); | |||
| ifn!(intrinsics, "llvm.frameaddress", [Type::i32()], Type::i8p()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.memcpy.p0i8.p0i8.i32", | |||
| [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); | |||
| @@ -2759,116 +2765,6 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { | |||
| ifn!(intrinsics, "llvm.memset.p0i8.i64", | |||
| [i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.trap", [], Type::void()); | |||
| ifn!(intrinsics, "llvm.frameaddress", [Type::i32()], i8p); | |||
|
|
|||
| ifn!(intrinsics, "llvm.powi.f32", [Type::f32(), Type::i32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.powi.f64", [Type::f64(), Type::i32()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.pow.f32", [Type::f32(), Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.pow.f64", [Type::f64(), Type::f64()], Type::f64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.sqrt.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.sqrt.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.sin.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.sin.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.cos.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.cos.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.exp.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.exp.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.exp2.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.exp2.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.log.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.log.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.log10.f32",[Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.log10.f64",[Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.log2.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.log2.f64", [Type::f64()], Type::f64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.fma.f32", [Type::f32(), Type::f32(), Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.fma.f64", [Type::f64(), Type::f64(), Type::f64()], Type::f64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.fabs.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.fabs.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.floor.f32",[Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.floor.f64",[Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.ceil.f32", [Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.ceil.f64", [Type::f64()], Type::f64()); | |||
| ifn!(intrinsics, "llvm.trunc.f32",[Type::f32()], Type::f32()); | |||
| ifn!(intrinsics, "llvm.trunc.f64",[Type::f64()], Type::f64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.ctpop.i8", [Type::i8()], Type::i8()); | |||
| ifn!(intrinsics, "llvm.ctpop.i16",[Type::i16()], Type::i16()); | |||
| ifn!(intrinsics, "llvm.ctpop.i32",[Type::i32()], Type::i32()); | |||
| ifn!(intrinsics, "llvm.ctpop.i64",[Type::i64()], Type::i64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.ctlz.i8", [Type::i8() , Type::i1()], Type::i8()); | |||
| ifn!(intrinsics, "llvm.ctlz.i16", [Type::i16(), Type::i1()], Type::i16()); | |||
| ifn!(intrinsics, "llvm.ctlz.i32", [Type::i32(), Type::i1()], Type::i32()); | |||
| ifn!(intrinsics, "llvm.ctlz.i64", [Type::i64(), Type::i1()], Type::i64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.cttz.i8", [Type::i8() , Type::i1()], Type::i8()); | |||
| ifn!(intrinsics, "llvm.cttz.i16", [Type::i16(), Type::i1()], Type::i16()); | |||
| ifn!(intrinsics, "llvm.cttz.i32", [Type::i32(), Type::i1()], Type::i32()); | |||
| ifn!(intrinsics, "llvm.cttz.i64", [Type::i64(), Type::i1()], Type::i64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.bswap.i16",[Type::i16()], Type::i16()); | |||
| ifn!(intrinsics, "llvm.bswap.i32",[Type::i32()], Type::i32()); | |||
| ifn!(intrinsics, "llvm.bswap.i64",[Type::i64()], Type::i64()); | |||
|
|
|||
| ifn!(intrinsics, "llvm.sadd.with.overflow.i8", | |||
| [Type::i8(), Type::i8()], Type::struct_([Type::i8(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.sadd.with.overflow.i16", | |||
| [Type::i16(), Type::i16()], Type::struct_([Type::i16(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.sadd.with.overflow.i32", | |||
| [Type::i32(), Type::i32()], Type::struct_([Type::i32(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.sadd.with.overflow.i64", | |||
| [Type::i64(), Type::i64()], Type::struct_([Type::i64(), Type::i1()], false)); | |||
|
|
|||
| ifn!(intrinsics, "llvm.uadd.with.overflow.i8", | |||
| [Type::i8(), Type::i8()], Type::struct_([Type::i8(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.uadd.with.overflow.i16", | |||
| [Type::i16(), Type::i16()], Type::struct_([Type::i16(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.uadd.with.overflow.i32", | |||
| [Type::i32(), Type::i32()], Type::struct_([Type::i32(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.uadd.with.overflow.i64", | |||
| [Type::i64(), Type::i64()], Type::struct_([Type::i64(), Type::i1()], false)); | |||
|
|
|||
| ifn!(intrinsics, "llvm.ssub.with.overflow.i8", | |||
| [Type::i8(), Type::i8()], Type::struct_([Type::i8(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.ssub.with.overflow.i16", | |||
| [Type::i16(), Type::i16()], Type::struct_([Type::i16(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.ssub.with.overflow.i32", | |||
| [Type::i32(), Type::i32()], Type::struct_([Type::i32(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.ssub.with.overflow.i64", | |||
| [Type::i64(), Type::i64()], Type::struct_([Type::i64(), Type::i1()], false)); | |||
|
|
|||
| ifn!(intrinsics, "llvm.usub.with.overflow.i8", | |||
| [Type::i8(), Type::i8()], Type::struct_([Type::i8(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.usub.with.overflow.i16", | |||
| [Type::i16(), Type::i16()], Type::struct_([Type::i16(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.usub.with.overflow.i32", | |||
| [Type::i32(), Type::i32()], Type::struct_([Type::i32(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.usub.with.overflow.i64", | |||
| [Type::i64(), Type::i64()], Type::struct_([Type::i64(), Type::i1()], false)); | |||
|
|
|||
| ifn!(intrinsics, "llvm.smul.with.overflow.i8", | |||
| [Type::i8(), Type::i8()], Type::struct_([Type::i8(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.smul.with.overflow.i16", | |||
| [Type::i16(), Type::i16()], Type::struct_([Type::i16(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.smul.with.overflow.i32", | |||
| [Type::i32(), Type::i32()], Type::struct_([Type::i32(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.smul.with.overflow.i64", | |||
| [Type::i64(), Type::i64()], Type::struct_([Type::i64(), Type::i1()], false)); | |||
|
|
|||
| ifn!(intrinsics, "llvm.umul.with.overflow.i8", | |||
| [Type::i8(), Type::i8()], Type::struct_([Type::i8(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.umul.with.overflow.i16", | |||
| [Type::i16(), Type::i16()], Type::struct_([Type::i16(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.umul.with.overflow.i32", | |||
| [Type::i32(), Type::i32()], Type::struct_([Type::i32(), Type::i1()], false)); | |||
| ifn!(intrinsics, "llvm.umul.with.overflow.i64", | |||
| [Type::i64(), Type::i64()], Type::struct_([Type::i64(), Type::i1()], false)); | |||
|
|
|||
| return intrinsics; | |||
| } | |||
|
|
|||
| @@ -26,6 +26,7 @@ use middle::trans::type_of; | |||
| use middle::ty; | |||
| use middle::ty::FnSig; | |||
|
|
|||
| use std::str; | |||
| use std::uint; | |||
| use std::vec; | |||
| use syntax::codemap::Span; | |||
| @@ -326,8 +327,48 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, | |||
| foreign_mod: &ast::foreign_mod) { | |||
| let _icx = push_ctxt("foreign::trans_foreign_mod"); | |||
| for &foreign_item in foreign_mod.items.iter() { | |||
| let lname = link_name(ccx, foreign_item); | |||
| ccx.item_symbols.insert(foreign_item.id, lname.to_owned()); | |||
| let name = link_name(ccx, foreign_item); | |||
|
|
|||
| match foreign_item.node { | |||
| ast::foreign_item_raw_ir(ir) => { | |||
| do ir.to_c_str().with_ref |c| { | |||
| unsafe { | |||
| let r = llvm::LLVMRustAddRawIR(ccx.llmod, c); | |||
|
|
|||
| if !r { | |||
| let cstr = llvm::LLVMRustGetLastError(); | |||
|
|
|||
| ccx.sess.fatal(fmt!("Adding raw IR: %s", | |||
| str::raw::from_c_str(cstr))); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ast::foreign_item_fn(*) | ast::foreign_item_static(*) => {} | |||
| ast::foreign_item_ir_fn(_, ir) => { | |||
| let tys = foreign_types_for_id(ccx, foreign_item.id); | |||
|
|
|||
| // Create the LLVM value for the C extern fn | |||
| let fn_ty = lltype_for_fn_from_foreign_types(&tys); | |||
|
|
|||
| do name.to_c_str().with_ref |n| { | |||
| do ir.to_c_str().with_ref |c| { | |||
| unsafe { | |||
| let r = llvm::LLVMRustCreateIRFunction(ccx.llmod, fn_ty.to_ref(), n, c); | |||
|
|
|||
| if !r { | |||
| let cstr = llvm::LLVMRustGetLastError(); | |||
|
|
|||
| ccx.sess.fatal(fmt!("Adding IR function: %s", | |||
| str::raw::from_c_str(cstr))); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
|
|
|||
| ccx.item_symbols.insert(foreign_item.id, name.to_owned()); | |||
| } | |||
| } | |||
|
|
|||
Oops, something went wrong.