Skip to content

Commit 6244fd9

Browse files
committed
---
yaml --- r: 227037 b: refs/heads/master c: 9af385b h: refs/heads/master i: 227035: 31dde13 v: v3
1 parent 9dadc93 commit 6244fd9

File tree

9 files changed

+274
-4
lines changed

9 files changed

+274
-4
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 1bfbde6778ee4839ca62aad3d025477296cf323f
2+
refs/heads/master: 9af385bddb3076637ab299672c90702562644894
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
44
refs/heads/try: b53c0f93eedcdedd4fd89bccc5a3a09d1c5cd23e
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

trunk/mk/crates.mk

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ TARGET_CRATES := libc std flate arena term \
5656
alloc_system
5757
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
5858
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
59-
rustc_data_structures
59+
rustc_data_structures rustc_platform_intrinsics
6060
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
6161
TOOLS := compiletest rustdoc rustc rustbook error-index-generator
6262

@@ -74,7 +74,7 @@ DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_bo
7474
rustc_trans rustc_privacy rustc_lint
7575

7676
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
77-
log syntax serialize rustc_llvm
77+
log syntax serialize rustc_llvm rustc_platform_intrinsics
7878
DEPS_rustc_typeck := rustc syntax
7979
DEPS_rustc_borrowck := rustc log graphviz syntax
8080
DEPS_rustc_resolve := rustc log syntax
@@ -83,6 +83,7 @@ DEPS_rustc_lint := rustc log syntax
8383
DEPS_rustc := syntax flate arena serialize getopts rbml \
8484
log graphviz rustc_llvm rustc_back rustc_data_structures
8585
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
86+
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
8687
DEPS_rustc_back := std syntax rustc_llvm flate log libc
8788
DEPS_rustc_data_structures := std log serialize
8889
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use {Intrinsic, i, f, v};
12+
use rustc::middle::ty;
13+
14+
macro_rules! p {
15+
($name: expr, ($($inputs: tt),*) -> $output: tt) => {
16+
plain!(concat!("llvm.aarch64.neon.", $name), ($($inputs),*) -> $output)
17+
}
18+
}
19+
pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
20+
Some(match name {
21+
"vmaxvq_u8" => p!("umaxv.i8.v16i8", (i8x16) -> i8),
22+
"vmaxvq_u16" => p!("umaxv.i16.v8i16", (i16x8) -> i16),
23+
"vmaxvq_u32" => p!("umaxv.i32.v4i32", (i32x4) -> i32),
24+
25+
"vmaxvq_s8" => p!("smaxv.i8.v16i8", (i8x16) -> i8),
26+
"vmaxvq_s16" => p!("smaxv.i16.v8i16", (i16x8) -> i16),
27+
"vmaxvq_s32" => p!("smaxv.i32.v4i32", (i32x4) -> i32),
28+
29+
"vminvq_u8" => p!("uminv.i8.v16i8", (i8x16) -> i8),
30+
"vminvq_u16" => p!("uminv.i16.v8i16", (i16x8) -> i16),
31+
"vminvq_u32" => p!("uminv.i32.v4i32", (i32x4) -> i32),
32+
"vminvq_s8" => p!("sminv.i8.v16i8", (i8x16) -> i8),
33+
"vminvq_s16" => p!("sminv.i16.v8i16", (i16x8) -> i16),
34+
"vminvq_s32" => p!("sminv.i32.v4i32", (i32x4) -> i32),
35+
36+
"vsqrtq_f32" => plain!("llvm.sqrt.v4f32", (f32x4) -> f32x4),
37+
"vsqrtq_f64" => plain!("llvm.sqrt.v2f64", (f64x2) -> f64x2),
38+
39+
"vrsqrteq_f32" => p!("vrsqrte.v4f32", (f32x4) -> f32x4),
40+
"vrsqrteq_f64" => p!("vrsqrte.v2f64", (f64x2) -> f64x2),
41+
42+
"vmaxq_f32" => p!("fmax.v4f32", (f32x4, f32x4) -> f32x4),
43+
"vmaxq_f64" => p!("fmax.v2f64", (f64x2, f64x2) -> f64x2),
44+
45+
"vminq_f32" => p!("fmin.v4f32", (f32x4, f32x4) -> f32x4),
46+
"vminq_f64" => p!("fmin.v2f64", (f64x2, f64x2) -> f64x2),
47+
_ => return None,
48+
})
49+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use {Intrinsic, i, f, v};
12+
use rustc::middle::ty;
13+
14+
macro_rules! p {
15+
($name: expr, ($($inputs: tt),*) -> $output: tt) => {
16+
plain!(concat!("llvm.arm.neon.", $name), ($($inputs),*) -> $output)
17+
}
18+
}
19+
pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
20+
Some(match name {
21+
"vpmax_u8" => p!("vpmaxu.v8i8", (i8x8, i8x8) -> i8x8),
22+
"vpmax_s8" => p!("vpmaxs.v8i8", (i8x8, i8x8) -> i8x8),
23+
"vpmax_u16" => p!("vpmaxu.v4i16", (i16x4, i16x4) -> i16x4),
24+
"vpmax_s16" => p!("vpmaxs.v4i16", (i16x4, i16x4) -> i16x4),
25+
"vpmax_u32" => p!("vpmaxu.v2i32", (i32x2, i32x2) -> i32x2),
26+
"vpmax_s32" => p!("vpmaxs.v2i32", (i32x2, i32x2) -> i32x2),
27+
28+
"vpmin_u8" => p!("vpminu.v8i8", (i8x8, i8x8) -> i8x8),
29+
"vpmin_s8" => p!("vpmins.v8i8", (i8x8, i8x8) -> i8x8),
30+
"vpmin_u16" => p!("vpminu.v4i16", (i16x4, i16x4) -> i16x4),
31+
"vpmin_s16" => p!("vpmins.v4i16", (i16x4, i16x4) -> i16x4),
32+
"vpmin_u32" => p!("vpminu.v2i32", (i32x2, i32x2) -> i32x2),
33+
"vpmin_s32" => p!("vpmins.v2i32", (i32x2, i32x2) -> i32x2),
34+
35+
"vsqrtq_f32" => plain!("llvm.sqrt.v4f32", (f32x4) -> f32x4),
36+
"vsqrtq_f64" => plain!("llvm.sqrt.v2f64", (f64x2) -> f64x2),
37+
38+
"vrsqrteq_f32" => p!("vrsqrte.v4f32", (f32x4) -> f32x4),
39+
"vrsqrteq_f64" => p!("vrsqrte.v2f64", (f64x2) -> f64x2),
40+
41+
"vmaxq_f32" => p!("vmaxs.v4f32", (f32x4, f32x4) -> f32x4),
42+
43+
"vminq_f32" => p!("vmins.v4f32", (f32x4, f32x4) -> f32x4),
44+
_ => return None,
45+
})
46+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![cfg_attr(stage0, feature(custom_attribute))]
12+
#![crate_name = "rustc_platform_intrinsics"]
13+
#![unstable(feature = "rustc_private", issue = "27812")]
14+
#![staged_api]
15+
#![crate_type = "dylib"]
16+
#![crate_type = "rlib"]
17+
#![feature(staged_api, rustc_private)]
18+
19+
extern crate rustc_llvm as llvm;
20+
extern crate rustc;
21+
22+
use rustc::middle::ty;
23+
24+
pub struct Intrinsic {
25+
pub inputs: Vec<Type>,
26+
pub output: Type,
27+
28+
pub definition: IntrinsicDef,
29+
}
30+
31+
#[derive(Clone)]
32+
pub enum Type {
33+
Integer(u8),
34+
Float(u8),
35+
Pointer(Box<Type>),
36+
Vector(Box<Type>, u8),
37+
}
38+
39+
pub enum IntrinsicDef {
40+
Named(&'static str),
41+
}
42+
43+
fn i(width: u8) -> Type { Type::Integer(width) }
44+
fn f(width: u8) -> Type { Type::Float(width) }
45+
fn v(x: Type, length: u8) -> Type { Type::Vector(Box::new(x), length) }
46+
47+
macro_rules! ty {
48+
(f32x4) => (v(f(32), 4));
49+
(f64x2) => (v(f(64), 2));
50+
51+
(i8x16) => (v(i(8), 16));
52+
(i16x8) => (v(i(16), 8));
53+
(i32x4) => (v(i(32), 4));
54+
(i64x2) => (v(i(64), 2));
55+
56+
(f32x2) => (v(f(32), 2));
57+
(i8x8) => (v(i(8), 8));
58+
(i16x4) => (v(i(16), 4));
59+
(i32x2) => (v(i(32), 2));
60+
61+
(i64) => (i(64));
62+
(i32) => (i(32));
63+
(i16) => (i(16));
64+
(i8) => (i(8));
65+
(f32) => (f(32));
66+
(f64) => (f(64));
67+
}
68+
macro_rules! plain {
69+
($name: expr, ($($inputs: tt),*) -> $output: tt) => {
70+
Intrinsic {
71+
inputs: vec![$(ty!($inputs)),*],
72+
output: ty!($output),
73+
definition: ::IntrinsicDef::Named($name)
74+
}
75+
}
76+
}
77+
78+
mod x86;
79+
mod arm;
80+
mod aarch64;
81+
82+
impl Intrinsic {
83+
pub fn find<'tcx>(tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
84+
if name.starts_with("x86_") {
85+
x86::find(tcx, &name["x86_".len()..])
86+
} else if name.starts_with("arm_") {
87+
arm::find(tcx, &name["arm_".len()..])
88+
} else if name.starts_with("aarch64_") {
89+
aarch64::find(tcx, &name["aarch64_".len()..])
90+
} else {
91+
None
92+
}
93+
}
94+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use {Intrinsic, i, f, v};
12+
use rustc::middle::ty;
13+
14+
macro_rules! p {
15+
($name: expr, ($($inputs: tt),*) -> $output: tt) => {
16+
plain!(concat!("llvm.x86.", $name), ($($inputs),*) -> $output)
17+
}
18+
}
19+
20+
pub fn find<'tcx>(_tcx: &ty::ctxt<'tcx>, name: &str) -> Option<Intrinsic> {
21+
Some(match name {
22+
"mm_movemask_ps" => p!("sse.movmsk.ps", (f32x4) -> i32),
23+
"mm_movemask_pd" => p!("sse2.movmsk.pd", (f64x2) -> i32),
24+
"mm_movemask_epi8" => p!("sse2.pmovmskb.128", (i8x16) -> i32),
25+
26+
"mm_rsqrt_ps" => p!("sse.rsqrt.ps", (f32x4) -> f32x4),
27+
28+
"mm_sqrt_ps" => plain!("llvm.sqrt.v4f32", (f32x4) -> f32x4),
29+
"mm_sqrt_pd" => plain!("llvm.sqrt.v2f64", (f64x2) -> f64x2),
30+
31+
"mm_max_ps" => p!("sse.max.ps", (f32x4, f32x4) -> f32x4),
32+
"mm_max_pd" => p!("sse2.max.pd", (f64x2, f64x2) -> f64x2),
33+
34+
"mm_min_ps" => p!("sse.min.ps", (f32x4, f32x4) -> f32x4),
35+
"mm_min_pd" => p!("sse2.min.pd", (f64x2, f64x2) -> f64x2),
36+
_ => return None
37+
})
38+
}

trunk/src/librustc_trans/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ extern crate libc;
5454
extern crate rustc;
5555
extern crate rustc_back;
5656
extern crate rustc_llvm as llvm;
57+
extern crate rustc_platform_intrinsics as intrinsics;
5758
extern crate serialize;
5859

5960
#[macro_use] extern crate log;

trunk/src/librustc_trans/trans/intrinsic.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![allow(non_upper_case_globals)]
1212

1313
use arena::TypedArena;
14+
use intrinsics::{self, Intrinsic};
1415
use llvm;
1516
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
1617
use middle::subst;
@@ -905,7 +906,41 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
905906

906907
}
907908

908-
(_, _) => ccx.sess().span_bug(foreign_item.span, "unknown intrinsic")
909+
(_, _) => {
910+
match Intrinsic::find(tcx, &name) {
911+
None => ccx.sess().span_bug(foreign_item.span, "unknown intrinsic"),
912+
Some(intr) => {
913+
fn ty_to_type(ccx: &CrateContext, t: &intrinsics::Type) -> Type {
914+
use intrinsics::Type::*;
915+
match *t {
916+
Integer(x) => Type::ix(ccx, x as u64),
917+
Float(x) => {
918+
match x {
919+
32 => Type::f32(ccx),
920+
64 => Type::f64(ccx),
921+
_ => unreachable!()
922+
}
923+
}
924+
Pointer(_) => unimplemented!(),
925+
Vector(ref t, length) => Type::vector(&ty_to_type(ccx, t),
926+
length as u64)
927+
}
928+
}
929+
930+
let inputs = intr.inputs.iter().map(|t| ty_to_type(ccx, t)).collect::<Vec<_>>();
931+
let outputs = ty_to_type(ccx, &intr.output);
932+
match intr.definition {
933+
intrinsics::IntrinsicDef::Named(name) => {
934+
let f = declare::declare_cfn(ccx,
935+
name,
936+
Type::func(&inputs, &outputs),
937+
tcx.mk_nil());
938+
Call(bcx, f, &llargs, None, call_debug_location)
939+
}
940+
}
941+
}
942+
}
943+
}
909944
};
910945

911946
if val_ty(llval) != Type::void(ccx) &&

trunk/src/librustc_typeck/check/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5378,6 +5378,12 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
53785378
(0, vec![tcx.mk_fn(None, fn_ty), mut_u8], mut_u8)
53795379
}
53805380

5381+
name if name.starts_with("x86_") ||
5382+
name.starts_with("arm_") ||
5383+
name.starts_with("aarch64_") => {
5384+
// FIXME: skip checking these for now
5385+
return
5386+
}
53815387
ref other => {
53825388
span_err!(tcx.sess, it.span, E0093,
53835389
"unrecognized intrinsic function: `{}`", *other);

0 commit comments

Comments
 (0)