unsigned mask = 0;
unsigned TV = 0;
- bool HasPtr = false;
+ int PtrArgNum = -1;
bool HasConstPtr = false;
switch (BuiltinID) {
#define GET_NEON_OVERLOAD_CHECK
<< TheCall->getArg(ImmArg)->getSourceRange();
}
- if (HasPtr || HasConstPtr) {
+ if (PtrArgNum >= 0) {
// Check that pointer arguments have the specified type.
- for (unsigned ArgNo = 0; ArgNo < ImmArg; ++ArgNo) {
- Expr *Arg = TheCall->getArg(ArgNo);
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = ICE->getSubExpr();
- ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg);
- QualType RHSTy = RHS.get()->getType();
- if (!RHSTy->isPointerType())
- continue;
- QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context);
- if (HasConstPtr)
- EltTy = EltTy.withConst();
- QualType LHSTy = Context.getPointerType(EltTy);
- AssignConvertType ConvTy;
- ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
- if (RHS.isInvalid())
- return true;
- if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy, RHSTy,
- RHS.get(), AA_Assigning))
- return true;
- }
+ Expr *Arg = TheCall->getArg(PtrArgNum);
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg))
+ Arg = ICE->getSubExpr();
+ ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg);
+ QualType RHSTy = RHS.get()->getType();
+ QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context);
+ if (HasConstPtr)
+ EltTy = EltTy.withConst();
+ QualType LHSTy = Context.getPointerType(EltTy);
+ AssignConvertType ConvTy;
+ ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
+ if (RHS.isInvalid())
+ return true;
+ if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy, RHSTy,
+ RHS.get(), AA_Assigning))
+ return true;
}
// For NEON intrinsics which take an immediate value as part of the
mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]);
}
}
- bool HasPtr = (Proto.find('p') != std::string::npos);
- bool HasConstPtr = (Proto.find('c') != std::string::npos);
+
+ // Check if the builtin function has a pointer or const pointer argument.
+ int PtrArgNum = -1;
+ bool HasConstPtr = false;
+ for (unsigned arg = 1, arge = Proto.size(); arg != arge; ++arg) {
+ char ArgType = Proto[arg];
+ if (ArgType == 'c') {
+ HasConstPtr = true;
+ PtrArgNum = arg - 1;
+ break;
+ }
+ if (ArgType == 'p') {
+ PtrArgNum = arg - 1;
+ break;
+ }
+ }
+ // For sret builtins, adjust the pointer argument index.
+ if (PtrArgNum >= 0 && (Proto[0] >= '2' && Proto[0] <= '4'))
+ PtrArgNum += 1;
+
if (mask) {
OS << "case ARM::BI__builtin_neon_"
<< MangleName(name, TypeVec[si], ClassB)
<< ": mask = " << "0x" << utohexstr(mask);
- if (HasPtr)
- OS << "; HasPtr = true";
+ if (PtrArgNum >= 0)
+ OS << "; PtrArgNum = " << PtrArgNum;
if (HasConstPtr)
OS << "; HasConstPtr = true";
OS << "; break;\n";
OS << "case ARM::BI__builtin_neon_"
<< MangleName(name, TypeVec[qi], ClassB)
<< ": mask = " << "0x" << utohexstr(qmask);
- if (HasPtr)
- OS << "; HasPtr = true";
+ if (PtrArgNum >= 0)
+ OS << "; PtrArgNum = " << PtrArgNum;
if (HasConstPtr)
OS << "; HasConstPtr = true";
OS << "; break;\n";