Add support for naked functions

This commit is contained in:
Ticki 2016-03-21 21:01:08 +01:00
parent 0215681744
commit 1605ab377b
3 changed files with 22 additions and 0 deletions

View File

@ -1905,6 +1905,8 @@ type int8_t = i8;
- `should_panic` - indicates that this test function should panic, inverting the success condition.
- `cold` - The function is unlikely to be executed, so optimize it (and calls
to it) differently.
- `naked` - The function utilizes a custom ABI or custom inline ASM that requires
epilogue and prologue to be skipped.
### Static-only attributes

View File

@ -81,6 +81,18 @@ pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
}
}
/// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue.
#[inline]
pub fn naked(val: ValueRef, is_naked: bool) {
if is_naked {
llvm::SetFunctionAttribute(val, llvm::Attribute::Naked);
} else {
unsafe {
llvm::LLVMRemoveFunctionAttr(val, llvm::Attribute::Naked.bits() as c_ulonglong);
}
}
}
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
@ -105,6 +117,8 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
if attr.check_name("cold") {
llvm::Attributes::default().set(llvm::Attribute::Cold)
.apply_llfn(llvm::FunctionIndex as usize, llfn)
} else if attr.check_name("naked") {
naked(llfn, true);
} else if attr.check_name("allocator") {
llvm::Attributes::default().set(llvm::Attribute::NoAlias)
.apply_llfn(llvm::ReturnIndex as usize, llfn)

View File

@ -212,6 +212,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
// rust runtime internal
("unwind_attributes", "1.4.0", None, Active),
// allow the use of `#[naked]` on functions.
("naked_functions", "1.9.0", None, Active),
// allow empty structs and enum variants with braces
("braced_empty_structs", "1.5.0", Some(29720), Accepted),
@ -376,6 +379,9 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
// FIXME: #14406 these are processed in trans, which happens after the
// lint pass
("cold", Whitelisted, Ungated),
("naked", Whitelisted, Gated("naked_functions",
"the `#[naked]` attribute \
is an experimental feature")),
("export_name", Whitelisted, Ungated),
("inline", Whitelisted, Ungated),
("link", Whitelisted, Ungated),