1. Add some ABI information for the Microblaze.
2. Add attibutes "interrupt_handler" and "save_volatiles" for the Microblaze target. llvm-svn: 122184
This commit is contained in:
parent
3e635d2e99
commit
36a1f68fec
|
@ -279,6 +279,14 @@ def MSP430Interrupt : Attr {
|
||||||
let Args = [UnsignedArgument<"Number">];
|
let Args = [UnsignedArgument<"Number">];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def MBlazeInterruptHandler : Attr {
|
||||||
|
let Spellings = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
def MBlazeSaveVolatiles : Attr {
|
||||||
|
let Spellings = [];
|
||||||
|
}
|
||||||
|
|
||||||
def Naked : Attr {
|
def Naked : Attr {
|
||||||
let Spellings = ["naked"];
|
let Spellings = ["naked"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2529,6 +2529,116 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
|
||||||
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// 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
|
// MSP430 ABI Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -2654,6 +2764,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
|
||||||
case llvm::Triple::systemz:
|
case llvm::Triple::systemz:
|
||||||
return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types));
|
return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types));
|
||||||
|
|
||||||
|
case llvm::Triple::mblaze:
|
||||||
|
return *(TheTargetCodeGenInfo = new MBlazeTargetCodeGenInfo(Types));
|
||||||
|
|
||||||
case llvm::Triple::msp430:
|
case llvm::Triple::msp430:
|
||||||
return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types));
|
return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types));
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,55 @@ namespace {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void HandleMBlazeInterruptHandlerAttr(Decl *d, const AttributeList &Attr,
|
||||||
|
Sema &S) {
|
||||||
|
// Check the attribute arguments.
|
||||||
|
if (Attr.getNumArgs() != 0) {
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Check for decl - it should be void ()(void).
|
||||||
|
|
||||||
|
d->addAttr(::new (S.Context) MBlazeInterruptHandlerAttr(Attr.getLoc(),
|
||||||
|
S.Context));
|
||||||
|
d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleMBlazeSaveVolatilesAttr(Decl *d, const AttributeList &Attr,
|
||||||
|
Sema &S) {
|
||||||
|
// Check the attribute arguments.
|
||||||
|
if (Attr.getNumArgs() != 0) {
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Check for decl - it should be void ()(void).
|
||||||
|
|
||||||
|
d->addAttr(::new (S.Context) MBlazeSaveVolatilesAttr(Attr.getLoc(),
|
||||||
|
S.Context));
|
||||||
|
d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class MBlazeAttributesSema : public TargetAttributesSema {
|
||||||
|
public:
|
||||||
|
MBlazeAttributesSema() { }
|
||||||
|
bool ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr,
|
||||||
|
Sema &S) const {
|
||||||
|
if (Attr.getName()->getName() == "interrupt_handler") {
|
||||||
|
HandleMBlazeInterruptHandlerAttr(D, Attr, S);
|
||||||
|
return true;
|
||||||
|
} else if (Attr.getName()->getName() == "save_volatiles") {
|
||||||
|
HandleMBlazeSaveVolatilesAttr(D, Attr, S);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static void HandleX86ForceAlignArgPointerAttr(Decl *D,
|
static void HandleX86ForceAlignArgPointerAttr(Decl *D,
|
||||||
const AttributeList& Attr,
|
const AttributeList& Attr,
|
||||||
Sema &S) {
|
Sema &S) {
|
||||||
|
@ -220,6 +269,8 @@ const TargetAttributesSema &Sema::getTargetAttributesSema() const {
|
||||||
|
|
||||||
case llvm::Triple::msp430:
|
case llvm::Triple::msp430:
|
||||||
return *(TheTargetAttributesSema = new MSP430AttributesSema);
|
return *(TheTargetAttributesSema = new MSP430AttributesSema);
|
||||||
|
case llvm::Triple::mblaze:
|
||||||
|
return *(TheTargetAttributesSema = new MBlazeAttributesSema);
|
||||||
case llvm::Triple::x86:
|
case llvm::Triple::x86:
|
||||||
return *(TheTargetAttributesSema = new X86AttributesSema);
|
return *(TheTargetAttributesSema = new X86AttributesSema);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue