Add new #[target_feature = "..."] attribute. · rust-lang/rust@80ef1db (original) (raw)
`@@ -9,6 +9,8 @@
`
9
9
`// except according to those terms.
`
10
10
`//! Set and unset common attributes on LLVM values.
`
11
11
``
``
12
`+
use std::ffi::{CStr, CString};
`
``
13
+
12
14
`use llvm::{self, Attribute, ValueRef};
`
13
15
`use llvm::AttributePlace::Function;
`
14
16
`pub use syntax::attr::InlineAttr;
`
`@@ -61,10 +63,8 @@ pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) {
`
61
63
`// parameter.
`
62
64
`if ccx.sess().must_not_eliminate_frame_pointers() {
`
63
65
` llvm::AddFunctionAttrStringValue(
`
64
``
`-
llfn,
`
65
``
`-
llvm::AttributePlace::Function,
`
66
``
`-
"no-frame-pointer-elim\0",
`
67
``
`-
"true\0")
`
``
66
`+
llfn, llvm::AttributePlace::Function,
`
``
67
`+
cstr("no-frame-pointer-elim\0"), cstr("true\0"));
`
68
68
`}
`
69
69
`}
`
70
70
``
`@@ -75,9 +75,17 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
`
75
75
`inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));
`
76
76
``
77
77
`set_frame_pointer_elimination(ccx, llfn);
`
78
``
-
``
78
`+
let mut target_features = vec![];
`
79
79
`for attr in attrs {
`
80
``
`-
if attr.check_name("cold") {
`
``
80
`+
if attr.check_name("target_feature") {
`
``
81
`+
if let Some(val) = attr.value_str() {
`
``
82
`+
for feat in val.as_str().split(",").map(|f| f.trim()) {
`
``
83
`+
if !feat.is_empty() && !feat.contains('\0') {
`
``
84
`+
target_features.push(feat.to_string());
`
``
85
`+
}
`
``
86
`+
}
`
``
87
`+
}
`
``
88
`+
} else if attr.check_name("cold") {
`
81
89
`Attribute::Cold.apply_llfn(Function, llfn);
`
82
90
`} else if attr.check_name("naked") {
`
83
91
`naked(llfn, true);
`
`@@ -88,4 +96,14 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
`
88
96
`unwind(llfn, true);
`
89
97
`}
`
90
98
`}
`
``
99
`+
if !target_features.is_empty() {
`
``
100
`+
let val = CString::new(target_features.join(",")).unwrap();
`
``
101
`+
llvm::AddFunctionAttrStringValue(
`
``
102
`+
llfn, llvm::AttributePlace::Function,
`
``
103
`+
cstr("target-features\0"), &val);
`
``
104
`+
}
`
``
105
`+
}
`
``
106
+
``
107
`+
fn cstr(s: &'static str) -> &CStr {
`
``
108
`+
CStr::from_bytes_with_nul(s.as_bytes()).expect("null-terminated string")
`
91
109
`}
`