forked from OSchip/llvm-project
NeXT: Use objc_msgSend_fpret for calling functions which return
floating point. This is only correct for x86-32 at the moment. llvm-svn: 57667
This commit is contained in:
parent
252fe5c9f1
commit
3c683f5bf2
|
@ -41,8 +41,9 @@ class ObjCTypesHelper {
|
|||
private:
|
||||
CodeGen::CodeGenModule &CGM;
|
||||
|
||||
llvm::Function *MessageSendFn, *MessageSendStretFn;
|
||||
llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
|
||||
llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn;
|
||||
llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn,
|
||||
*MessageSendSuperFpretFn;
|
||||
|
||||
public:
|
||||
const llvm::Type *ShortTy, *IntTy, *LongTy;
|
||||
|
@ -159,7 +160,18 @@ public:
|
|||
ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
|
||||
~ObjCTypesHelper();
|
||||
|
||||
llvm::Constant *getMessageSendFn(bool IsSuper, bool isStret);
|
||||
|
||||
llvm::Function *getSendFn(bool IsSuper) {
|
||||
return IsSuper ? MessageSendSuperFn : MessageSendFn;
|
||||
}
|
||||
|
||||
llvm::Function *getSendStretFn(bool IsSuper) {
|
||||
return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
|
||||
}
|
||||
|
||||
llvm::Function *getSendFpretFn(bool IsSuper) {
|
||||
return IsSuper ? MessageSendSuperFpretFn : MessageSendFpretFn;
|
||||
}
|
||||
};
|
||||
|
||||
class CGObjCMac : public CodeGen::CGObjCRuntime {
|
||||
|
@ -534,8 +546,17 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
|
|||
const llvm::FunctionType *FTy =
|
||||
CGM.getTypes().GetFunctionType(CGCallInfo(ResultType, ActualArgs),
|
||||
false);
|
||||
llvm::Constant *Fn =
|
||||
ObjCTypes.getMessageSendFn(IsSuper, CGM.ReturnTypeUsesSret(ResultType));
|
||||
|
||||
llvm::Constant *Fn;
|
||||
if (CGM.ReturnTypeUsesSret(ResultType)) {
|
||||
Fn = ObjCTypes.getSendStretFn(IsSuper);
|
||||
} else if (ResultType->isFloatingType()) {
|
||||
// FIXME: Sadly, this is wrong. This actually depends on the
|
||||
// architecture. This happens to be right for x86-32 though.
|
||||
Fn = ObjCTypes.getSendFpretFn(IsSuper);
|
||||
} else {
|
||||
Fn = ObjCTypes.getSendFn(IsSuper);
|
||||
}
|
||||
Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
|
||||
return CGF.EmitCall(Fn, ResultType, ActualArgs);
|
||||
}
|
||||
|
@ -2224,6 +2245,16 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
true),
|
||||
"objc_msgSend_stret");
|
||||
|
||||
Params.clear();
|
||||
Params.push_back(ObjectPtrTy);
|
||||
Params.push_back(SelectorPtrTy);
|
||||
// FIXME: This should be long double on x86_64?
|
||||
MessageSendFpretFn =
|
||||
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::DoubleTy,
|
||||
Params,
|
||||
true),
|
||||
"objc_msgSend_fpret");
|
||||
|
||||
Params.clear();
|
||||
Params.push_back(SuperPtrTy);
|
||||
Params.push_back(SelectorPtrTy);
|
||||
|
@ -2243,6 +2274,9 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
true),
|
||||
"objc_msgSendSuper_stret");
|
||||
|
||||
// There is no objc_msgSendSuper_fpret? How can that work?
|
||||
MessageSendSuperFpretFn = MessageSendSuperFn;
|
||||
|
||||
// Property manipulation functions.
|
||||
|
||||
Params.clear();
|
||||
|
@ -2341,14 +2375,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
|
|||
ObjCTypesHelper::~ObjCTypesHelper() {
|
||||
}
|
||||
|
||||
llvm::Constant *ObjCTypesHelper::getMessageSendFn(bool IsSuper, bool IsStret) {
|
||||
if (IsStret) {
|
||||
return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
|
||||
} else { // FIXME: floating point?
|
||||
return IsSuper ? MessageSendSuperFn : MessageSendFn;
|
||||
}
|
||||
}
|
||||
|
||||
/* *** */
|
||||
|
||||
CodeGen::CGObjCRuntime *
|
||||
|
|
Loading…
Reference in New Issue