From c5ec8a78ea898087ad361e5b755f74a76150e5fd Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Fri, 17 Jul 2009 18:07:26 +0000 Subject: [PATCH] Add support for naked functions git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76198 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LangRef.html | 3 +++ include/llvm-c/Core.h | 3 ++- include/llvm/Attributes.h | 3 ++- lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 1 + lib/AsmParser/LLToken.h | 1 + lib/CodeGen/PrologEpilogInserter.cpp | 7 +++++-- lib/VMCore/Attributes.cpp | 4 +++- 8 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/LangRef.html b/docs/LangRef.html index 15f95e2a11c..4885a84192a 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -1109,6 +1109,9 @@ red zone, even if the target-specific ABI normally permits it.
noimplicitfloat
This attributes disables implicit floating point instructions.
+
naked
+
This attribute disables prologue / epilogue emission for the function
+ diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index d723d11111a..ee8058e8cc5 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -98,7 +98,8 @@ typedef enum { LLVMByValAttribute = 1<<7, LLVMNestAttribute = 1<<8, LLVMReadNoneAttribute = 1<<9, - LLVMReadOnlyAttribute = 1<<10 + LLVMReadOnlyAttribute = 1<<10, + LLVMNakedAttribute = 1<<24 } LLVMAttribute; typedef enum { diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 134e3502028..49f6057f31a 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -57,6 +57,7 @@ const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer const Attributes NoRedZone = 1<<22; /// disable redzone const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point /// instructions. +const Attributes Naked = 1<<24; ///< Naked function /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -65,7 +66,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// be used on return values or function parameters. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | - NoRedZone | NoImplicitFloat; + NoRedZone | NoImplicitFloat | Naked; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 97e8e6ad18b..1dc463110bc 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -541,6 +541,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(sspreq); KEYWORD(noredzone); KEYWORD(noimplicitfloat); + KEYWORD(naked); KEYWORD(type); KEYWORD(opaque); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 080575df84a..6a6478f37ba 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -775,6 +775,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break; + case lltok::kw_naked: Attrs |= Attribute::Naked; break; case lltok::kw_align: { unsigned Alignment; diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index b5194ad83f3..8f813f39b64 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -84,6 +84,7 @@ namespace lltok { kw_sspreq, kw_noredzone, kw_noimplicitfloat, + kw_naked, kw_type, kw_opaque, diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 546a84ec876..5aa37c9044d 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -51,6 +51,7 @@ FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } /// frame indexes with appropriate references. /// bool PEI::runOnMachineFunction(MachineFunction &Fn) { + const Function* F = Fn.getFunction(); const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; @@ -80,7 +81,8 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { placeCSRSpillsAndRestores(Fn); // Add the code to save and restore the callee saved registers - insertCSRSpillsAndRestores(Fn); + if (!F->hasFnAttr(Attribute::Naked)) + insertCSRSpillsAndRestores(Fn); // Allow the target machine to make final modifications to the function // before the frame layout is finalized. @@ -94,7 +96,8 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { // called functions. Because of this, calculateCalleeSavedRegisters // must be called before this function in order to set the HasCalls // and MaxCallFrameSize variables. - insertPrologEpilogCode(Fn); + if (!F->hasFnAttr(Attribute::Naked)) + insertPrologEpilogCode(Fn); // Replace all MO_FrameIndex operands with physical register references // and actual offsets. diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 8dfbd1d5021..5d763c34fe5 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -40,7 +40,7 @@ std::string Attribute::getAsString(Attributes Attrs) { if (Attrs & Attribute::NoCapture) Result += "nocapture "; if (Attrs & Attribute::StructRet) - Result += "sret "; + Result += "sret "; if (Attrs & Attribute::ByVal) Result += "byval "; if (Attrs & Attribute::Nest) @@ -63,6 +63,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "noredzone "; if (Attrs & Attribute::NoImplicitFloat) Result += "noimplicitfloat "; + if (Attrs & Attribute::Naked) + Result += "naked "; if (Attrs & Attribute::Alignment) { Result += "align "; Result += utostr(Attribute::getAlignmentFromAttrs(Attrs));