// // Returns of float, double and complex need to be handled with a helper // function. // static bool fixupFPReturnAndCall(Function &F, Module *M, const MipsTargetMachine &TM) { bool Modified = false; LLVMContext &C = M->getContext(); Type *MyVoid = Type::getVoidTy(C); for (auto &BB: F) for (auto &I: BB) { if (const ReturnInst *RI = dyn_cast<ReturnInst>(&I)) { Value *RVal = RI->getReturnValue(); if (!RVal) continue; // // If there is a return value and it needs a helper function, // figure out which one and add a call before the actual // return to this helper. The purpose of the helper is to move // floating point values from their soft float return mapping to // where they would have been mapped to in floating point registers. // Type *T = RVal->getType(); FPReturnVariant RV = whichFPReturnVariant(T); if (RV == NoFPRet) continue; static const char *const Helper[NoFPRet] = { "__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc", "__mips16_ret_dc" }; const char *Name = Helper[RV]; AttributeList A; Value *Params[] = {RVal}; Modified = true; // // These helper functions have a different calling ABI so // this __Mips16RetHelper indicates that so that later // during call setup, the proper call lowering to the helper // functions will take place. // A = A.addAttribute(C, AttributeList::FunctionIndex, "__Mips16RetHelper"); A = A.addAttribute(C, AttributeList::FunctionIndex, Attribute::ReadNone); A = A.addAttribute(C, AttributeList::FunctionIndex, Attribute::NoInline); Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T)); CallInst::Create(F, Params, "", &I); } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) { FunctionType *FT = CI->getFunctionType(); Function *F_ = CI->getCalledFunction(); if (needsFPReturnHelper(*FT) && !(F_ && isIntrinsicInline(F_))) { Modified=true; F.addFnAttr("saveS2"); } if (F_ && !isIntrinsicInline(F_)) { // pic mode calls are handled by already defined // helper functions if (needsFPReturnHelper(*F_)) { Modified=true; F.addFnAttr("saveS2"); } if (!TM.isPositionIndependent()) { if (needsFPHelperFromSig(*F_)) { assureFPCallStub(*F_, M, TM); Modified=true; } } } } } return Modified; }