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

`}

`