diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-12-19 19:57:51 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-12-19 19:57:51 +0000 |
commit | 276fdf408050d205f3a7f34c1e788224a67d2098 (patch) | |
tree | 67f326f51329deab4f9cbb21f84cd65457b84d56 /lib/CodeGen/TargetInfo.cpp | |
parent | 11542141e385859df6b4f1a8f1f01856ad193b5b (diff) |
1. Add some ABI information for the Microblaze.
2. Add attibutes "interrupt_handler" and "save_volatiles" for the Microblaze target.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122184 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 4234c6f337..5f7cf84386 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -2530,6 +2530,116 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { } //===----------------------------------------------------------------------===// +// MBlaze ABI Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class MBlazeABIInfo : public ABIInfo { +public: + MBlazeABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} + + bool isPromotableIntegerType(QualType Ty) const; + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType RetTy) const; + + virtual void computeInfo(CGFunctionInfo &FI) const { + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); + it != ie; ++it) + it->info = classifyArgumentType(it->type); + } + + virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const; +}; + +class MBlazeTargetCodeGenInfo : public TargetCodeGenInfo { +public: + MBlazeTargetCodeGenInfo(CodeGenTypes &CGT) + : TargetCodeGenInfo(new MBlazeABIInfo(CGT)) {} + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const; +}; + +} + +bool MBlazeABIInfo::isPromotableIntegerType(QualType Ty) const { + // MBlaze ABI requires all 8 and 16 bit quantities to be extended. + if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) + switch (BT->getKind()) { + case BuiltinType::Bool: + case BuiltinType::Char_S: + case BuiltinType::Char_U: + case BuiltinType::SChar: + case BuiltinType::UChar: + case BuiltinType::Short: + case BuiltinType::UShort: + return true; + default: + return false; + } + return false; +} + +llvm::Value *MBlazeABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + // FIXME: Implement + return 0; +} + + +ABIArgInfo MBlazeABIInfo::classifyReturnType(QualType RetTy) const { + if (RetTy->isVoidType()) + return ABIArgInfo::getIgnore(); + if (isAggregateTypeForABI(RetTy)) + return ABIArgInfo::getIndirect(0); + + return (isPromotableIntegerType(RetTy) ? + ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); +} + +ABIArgInfo MBlazeABIInfo::classifyArgumentType(QualType Ty) const { + if (isAggregateTypeForABI(Ty)) + return ABIArgInfo::getIndirect(0); + + return (isPromotableIntegerType(Ty) ? + ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); +} + +void MBlazeTargetCodeGenInfo::SetTargetAttributes(const Decl *D, + llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) + const { + const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); + if (!FD) return; + + llvm::CallingConv::ID CC = llvm::CallingConv::C; + if (FD->hasAttr<MBlazeInterruptHandlerAttr>()) + CC = llvm::CallingConv::MBLAZE_INTR; + else if (FD->hasAttr<MBlazeSaveVolatilesAttr>()) + CC = llvm::CallingConv::MBLAZE_SVOL; + + if (CC != llvm::CallingConv::C) { + // Handle 'interrupt_handler' attribute: + llvm::Function *F = cast<llvm::Function>(GV); + + // Step 1: Set ISR calling convention. + F->setCallingConv(CC); + + // Step 2: Add attributes goodness. + F->addFnAttr(llvm::Attribute::NoInline); + } + + // Step 3: Emit _interrupt_handler alias. + if (CC == llvm::CallingConv::MBLAZE_INTR) + new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, + "_interrupt_handler", GV, &M.getModule()); +} + + +//===----------------------------------------------------------------------===// // MSP430 ABI Implementation //===----------------------------------------------------------------------===// @@ -2654,6 +2764,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::systemz: return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types)); + case llvm::Triple::mblaze: + return *(TheTargetCodeGenInfo = new MBlazeTargetCodeGenInfo(Types)); + case llvm::Triple::msp430: return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types)); |