1ed35a92cSVlad Serebrennikov //===------ SemaPPC.cpp ------ PowerPC target-specific routines -----------===// 2ed35a92cSVlad Serebrennikov // 3ed35a92cSVlad Serebrennikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ed35a92cSVlad Serebrennikov // See https://llvm.org/LICENSE.txt for license information. 5ed35a92cSVlad Serebrennikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ed35a92cSVlad Serebrennikov // 7ed35a92cSVlad Serebrennikov //===----------------------------------------------------------------------===// 8ed35a92cSVlad Serebrennikov // 9ed35a92cSVlad Serebrennikov // This file implements semantic analysis functions specific to PowerPC. 10ed35a92cSVlad Serebrennikov // 11ed35a92cSVlad Serebrennikov //===----------------------------------------------------------------------===// 12ed35a92cSVlad Serebrennikov 13ed35a92cSVlad Serebrennikov #include "clang/Sema/SemaPPC.h" 14ed35a92cSVlad Serebrennikov #include "clang/AST/ASTContext.h" 15ed35a92cSVlad Serebrennikov #include "clang/AST/Attr.h" 16ed35a92cSVlad Serebrennikov #include "clang/AST/CharUnits.h" 17ed35a92cSVlad Serebrennikov #include "clang/AST/Decl.h" 18ed35a92cSVlad Serebrennikov #include "clang/AST/Type.h" 19ed35a92cSVlad Serebrennikov #include "clang/Basic/DiagnosticSema.h" 20ed35a92cSVlad Serebrennikov #include "clang/Basic/SourceLocation.h" 21ed35a92cSVlad Serebrennikov #include "clang/Basic/TargetBuiltins.h" 22*27d37ee4SVlad Serebrennikov #include "clang/Basic/TargetInfo.h" 23ed35a92cSVlad Serebrennikov #include "clang/Sema/Sema.h" 24ed35a92cSVlad Serebrennikov #include "llvm/ADT/APSInt.h" 25ed35a92cSVlad Serebrennikov 26ed35a92cSVlad Serebrennikov namespace clang { 27ed35a92cSVlad Serebrennikov 28ed35a92cSVlad Serebrennikov SemaPPC::SemaPPC(Sema &S) : SemaBase(S) {} 29ed35a92cSVlad Serebrennikov 30ed35a92cSVlad Serebrennikov void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) { 31ed35a92cSVlad Serebrennikov const auto *ICE = dyn_cast<ImplicitCastExpr>(Arg->IgnoreParens()); 32ed35a92cSVlad Serebrennikov if (!ICE) 33ed35a92cSVlad Serebrennikov return; 34ed35a92cSVlad Serebrennikov 35ed35a92cSVlad Serebrennikov const auto *DR = dyn_cast<DeclRefExpr>(ICE->getSubExpr()); 36ed35a92cSVlad Serebrennikov if (!DR) 37ed35a92cSVlad Serebrennikov return; 38ed35a92cSVlad Serebrennikov 39ed35a92cSVlad Serebrennikov const auto *PD = dyn_cast<ParmVarDecl>(DR->getDecl()); 40ed35a92cSVlad Serebrennikov if (!PD || !PD->getType()->isRecordType()) 41ed35a92cSVlad Serebrennikov return; 42ed35a92cSVlad Serebrennikov 43ed35a92cSVlad Serebrennikov QualType ArgType = Arg->getType(); 44ed35a92cSVlad Serebrennikov for (const FieldDecl *FD : 45ed35a92cSVlad Serebrennikov ArgType->castAs<RecordType>()->getDecl()->fields()) { 46ed35a92cSVlad Serebrennikov if (const auto *AA = FD->getAttr<AlignedAttr>()) { 47ed35a92cSVlad Serebrennikov CharUnits Alignment = getASTContext().toCharUnitsFromBits( 48ed35a92cSVlad Serebrennikov AA->getAlignment(getASTContext())); 49ed35a92cSVlad Serebrennikov if (Alignment.getQuantity() == 16) { 50ed35a92cSVlad Serebrennikov Diag(FD->getLocation(), diag::warn_not_xl_compatible) << FD; 51ed35a92cSVlad Serebrennikov Diag(Loc, diag::note_misaligned_member_used_here) << PD; 52ed35a92cSVlad Serebrennikov } 53ed35a92cSVlad Serebrennikov } 54ed35a92cSVlad Serebrennikov } 55ed35a92cSVlad Serebrennikov } 56ed35a92cSVlad Serebrennikov 57ed35a92cSVlad Serebrennikov static bool isPPC_64Builtin(unsigned BuiltinID) { 58ed35a92cSVlad Serebrennikov // These builtins only work on PPC 64bit targets. 59ed35a92cSVlad Serebrennikov switch (BuiltinID) { 60ed35a92cSVlad Serebrennikov case PPC::BI__builtin_divde: 61ed35a92cSVlad Serebrennikov case PPC::BI__builtin_divdeu: 62ed35a92cSVlad Serebrennikov case PPC::BI__builtin_bpermd: 63ed35a92cSVlad Serebrennikov case PPC::BI__builtin_pdepd: 64ed35a92cSVlad Serebrennikov case PPC::BI__builtin_pextd: 6564510c14SLei Huang case PPC::BI__builtin_ppc_cdtbcd: 6664510c14SLei Huang case PPC::BI__builtin_ppc_cbcdtd: 6764510c14SLei Huang case PPC::BI__builtin_ppc_addg6s: 68ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_ldarx: 69ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_stdcx: 70ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_tdw: 71ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_trapd: 72ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_cmpeqb: 73ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_setb: 74ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_mulhd: 75ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_mulhdu: 76ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_maddhd: 77ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_maddhdu: 78ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_maddld: 79ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_load8r: 80ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_store8r: 81ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_insert_exp: 82ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_extract_sig: 83ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_addex: 84ed35a92cSVlad Serebrennikov case PPC::BI__builtin_darn: 85ed35a92cSVlad Serebrennikov case PPC::BI__builtin_darn_raw: 86ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_compare_and_swaplp: 87ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_fetch_and_addlp: 88ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_fetch_and_andlp: 89ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_fetch_and_orlp: 90ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_fetch_and_swaplp: 91ed35a92cSVlad Serebrennikov return true; 92ed35a92cSVlad Serebrennikov } 93ed35a92cSVlad Serebrennikov return false; 94ed35a92cSVlad Serebrennikov } 95ed35a92cSVlad Serebrennikov 96ed35a92cSVlad Serebrennikov bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, 97ed35a92cSVlad Serebrennikov unsigned BuiltinID, 98ed35a92cSVlad Serebrennikov CallExpr *TheCall) { 99ed35a92cSVlad Serebrennikov ASTContext &Context = getASTContext(); 100ed35a92cSVlad Serebrennikov bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64; 101ed35a92cSVlad Serebrennikov llvm::APSInt Result; 102ed35a92cSVlad Serebrennikov 103ed35a92cSVlad Serebrennikov if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit) 104ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt) 105ed35a92cSVlad Serebrennikov << TheCall->getSourceRange(); 106ed35a92cSVlad Serebrennikov 107ed35a92cSVlad Serebrennikov switch (BuiltinID) { 108ed35a92cSVlad Serebrennikov default: 109ed35a92cSVlad Serebrennikov return false; 110ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_crypto_vshasigmaw: 111ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_crypto_vshasigmad: 112ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) || 113ed35a92cSVlad Serebrennikov SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15); 114ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_dss: 115ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3); 116ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tbegin: 117ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tend: 118ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1); 119ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tsr: 120ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7); 121ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tabortwc: 122ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tabortdc: 123ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31); 124ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tabortwci: 125ed35a92cSVlad Serebrennikov case PPC::BI__builtin_tabortdci: 126ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31) || 127ed35a92cSVlad Serebrennikov SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31); 128ed35a92cSVlad Serebrennikov // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05', 129ed35a92cSVlad Serebrennikov // __builtin_(un)pack_longdouble are available only if long double uses IBM 130ed35a92cSVlad Serebrennikov // extended double representation. 131ed35a92cSVlad Serebrennikov case PPC::BI__builtin_unpack_longdouble: 132ed35a92cSVlad Serebrennikov if (SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1)) 133ed35a92cSVlad Serebrennikov return true; 134ed35a92cSVlad Serebrennikov [[fallthrough]]; 135ed35a92cSVlad Serebrennikov case PPC::BI__builtin_pack_longdouble: 136ed35a92cSVlad Serebrennikov if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble()) 137ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi) 138ed35a92cSVlad Serebrennikov << "ibmlongdouble"; 139ed35a92cSVlad Serebrennikov return false; 140ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_dst: 141ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_dstt: 142ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_dstst: 143ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_dststt: 144ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3); 145ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxpermdi: 146ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxsldwi: 147ed35a92cSVlad Serebrennikov return BuiltinVSX(TheCall); 148ed35a92cSVlad Serebrennikov case PPC::BI__builtin_unpack_vector_int128: 149ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); 150ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vgnb: 151ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 2, 7); 152ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxeval: 153ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 255); 154ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vsldbi: 155ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7); 156ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vsrdbi: 157ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7); 158ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxpermx: 159ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7); 160ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_tw: 161ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_tdw: 162ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 31); 163ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_cmprb: 164ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1); 165ed35a92cSVlad Serebrennikov // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must 166ed35a92cSVlad Serebrennikov // be a constant that represents a contiguous bit field. 167ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_rlwnm: 168ed35a92cSVlad Serebrennikov return SemaRef.ValueIsRunOfOnes(TheCall, 2); 169ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_rlwimi: 170ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) || 171ed35a92cSVlad Serebrennikov SemaRef.ValueIsRunOfOnes(TheCall, 3); 172ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_rldimi: 173ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63) || 174ed35a92cSVlad Serebrennikov SemaRef.ValueIsRunOfOnes(TheCall, 3); 175ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_addex: { 176ed35a92cSVlad Serebrennikov if (SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3)) 177ed35a92cSVlad Serebrennikov return true; 178ed35a92cSVlad Serebrennikov // Output warning for reserved values 1 to 3. 179ed35a92cSVlad Serebrennikov int ArgValue = 180ed35a92cSVlad Serebrennikov TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue(); 181ed35a92cSVlad Serebrennikov if (ArgValue != 0) 182ed35a92cSVlad Serebrennikov Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour) 183ed35a92cSVlad Serebrennikov << ArgValue; 184ed35a92cSVlad Serebrennikov return false; 185ed35a92cSVlad Serebrennikov } 186ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_mtfsb0: 187ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_mtfsb1: 188ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31); 189ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_mtfsf: 190ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 255); 191ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_mtfsfi: 192ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7) || 193ed35a92cSVlad Serebrennikov SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15); 194ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_alignx: 195ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgPower2(TheCall, 0); 196ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_rdlam: 197ed35a92cSVlad Serebrennikov return SemaRef.ValueIsRunOfOnes(TheCall, 2); 198ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_ldrmb: 199ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_strmb: 200ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16); 201ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vcntmbb: 202ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vcntmbh: 203ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vcntmbw: 204ed35a92cSVlad Serebrennikov case PPC::BI__builtin_altivec_vcntmbd: 205ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1); 206ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxgenpcvbm: 207ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxgenpcvhm: 208ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxgenpcvwm: 209ed35a92cSVlad Serebrennikov case PPC::BI__builtin_vsx_xxgenpcvdm: 210ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3); 211ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_test_data_class: { 212ed35a92cSVlad Serebrennikov // Check if the first argument of the __builtin_ppc_test_data_class call is 213ed35a92cSVlad Serebrennikov // valid. The argument must be 'float' or 'double' or '__float128'. 214ed35a92cSVlad Serebrennikov QualType ArgType = TheCall->getArg(0)->getType(); 215ed35a92cSVlad Serebrennikov if (ArgType != QualType(Context.FloatTy) && 216ed35a92cSVlad Serebrennikov ArgType != QualType(Context.DoubleTy) && 217ed35a92cSVlad Serebrennikov ArgType != QualType(Context.Float128Ty)) 218ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), 219ed35a92cSVlad Serebrennikov diag::err_ppc_invalid_test_data_class_type); 220ed35a92cSVlad Serebrennikov return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 127); 221ed35a92cSVlad Serebrennikov } 222ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_maxfe: 223ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_minfe: 224ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_maxfl: 225ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_minfl: 226ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_maxfs: 227ed35a92cSVlad Serebrennikov case PPC::BI__builtin_ppc_minfs: { 228ed35a92cSVlad Serebrennikov if (Context.getTargetInfo().getTriple().isOSAIX() && 229ed35a92cSVlad Serebrennikov (BuiltinID == PPC::BI__builtin_ppc_maxfe || 230ed35a92cSVlad Serebrennikov BuiltinID == PPC::BI__builtin_ppc_minfe)) 231ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type) 232ed35a92cSVlad Serebrennikov << "builtin" << true << 128 << QualType(Context.LongDoubleTy) 233ed35a92cSVlad Serebrennikov << false << Context.getTargetInfo().getTriple().str(); 234ed35a92cSVlad Serebrennikov // Argument type should be exact. 235ed35a92cSVlad Serebrennikov QualType ArgType = QualType(Context.LongDoubleTy); 236ed35a92cSVlad Serebrennikov if (BuiltinID == PPC::BI__builtin_ppc_maxfl || 237ed35a92cSVlad Serebrennikov BuiltinID == PPC::BI__builtin_ppc_minfl) 238ed35a92cSVlad Serebrennikov ArgType = QualType(Context.DoubleTy); 239ed35a92cSVlad Serebrennikov else if (BuiltinID == PPC::BI__builtin_ppc_maxfs || 240ed35a92cSVlad Serebrennikov BuiltinID == PPC::BI__builtin_ppc_minfs) 241ed35a92cSVlad Serebrennikov ArgType = QualType(Context.FloatTy); 242ed35a92cSVlad Serebrennikov for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I) 243ed35a92cSVlad Serebrennikov if (TheCall->getArg(I)->getType() != ArgType) 244ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), 245ed35a92cSVlad Serebrennikov diag::err_typecheck_convert_incompatible) 246ed35a92cSVlad Serebrennikov << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0; 247ed35a92cSVlad Serebrennikov return false; 248ed35a92cSVlad Serebrennikov } 249ed35a92cSVlad Serebrennikov #define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature) \ 250ed35a92cSVlad Serebrennikov case PPC::BI__builtin_##Name: \ 251ed35a92cSVlad Serebrennikov return BuiltinPPCMMACall(TheCall, BuiltinID, Types); 252ed35a92cSVlad Serebrennikov #include "clang/Basic/BuiltinsPPC.def" 253ed35a92cSVlad Serebrennikov } 25404133283SMike Rice llvm_unreachable("must return from switch"); 255ed35a92cSVlad Serebrennikov } 256ed35a92cSVlad Serebrennikov 257ed35a92cSVlad Serebrennikov // Check if the given type is a non-pointer PPC MMA type. This function is used 258ed35a92cSVlad Serebrennikov // in Sema to prevent invalid uses of restricted PPC MMA types. 259ed35a92cSVlad Serebrennikov bool SemaPPC::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) { 260ed35a92cSVlad Serebrennikov ASTContext &Context = getASTContext(); 261ed35a92cSVlad Serebrennikov if (Type->isPointerType() || Type->isArrayType()) 262ed35a92cSVlad Serebrennikov return false; 263ed35a92cSVlad Serebrennikov 264ed35a92cSVlad Serebrennikov QualType CoreType = Type.getCanonicalType().getUnqualifiedType(); 265ed35a92cSVlad Serebrennikov #define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty 266ed35a92cSVlad Serebrennikov if (false 267ed35a92cSVlad Serebrennikov #include "clang/Basic/PPCTypes.def" 268ed35a92cSVlad Serebrennikov ) { 269ed35a92cSVlad Serebrennikov Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type); 270ed35a92cSVlad Serebrennikov return true; 271ed35a92cSVlad Serebrennikov } 272ed35a92cSVlad Serebrennikov return false; 273ed35a92cSVlad Serebrennikov } 274ed35a92cSVlad Serebrennikov 275ed35a92cSVlad Serebrennikov /// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str, 276ed35a92cSVlad Serebrennikov /// advancing the pointer over the consumed characters. The decoded type is 277ed35a92cSVlad Serebrennikov /// returned. If the decoded type represents a constant integer with a 278ed35a92cSVlad Serebrennikov /// constraint on its value then Mask is set to that value. The type descriptors 279ed35a92cSVlad Serebrennikov /// used in Str are specific to PPC MMA builtins and are documented in the file 280ed35a92cSVlad Serebrennikov /// defining the PPC builtins. 281ed35a92cSVlad Serebrennikov static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str, 282ed35a92cSVlad Serebrennikov unsigned &Mask) { 283ed35a92cSVlad Serebrennikov bool RequireICE = false; 284ed35a92cSVlad Serebrennikov ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None; 285ed35a92cSVlad Serebrennikov switch (*Str++) { 286ed35a92cSVlad Serebrennikov case 'V': 287ed35a92cSVlad Serebrennikov return Context.getVectorType(Context.UnsignedCharTy, 16, 288ed35a92cSVlad Serebrennikov VectorKind::AltiVecVector); 289ed35a92cSVlad Serebrennikov case 'i': { 290ed35a92cSVlad Serebrennikov char *End; 291ed35a92cSVlad Serebrennikov unsigned size = strtoul(Str, &End, 10); 292ed35a92cSVlad Serebrennikov assert(End != Str && "Missing constant parameter constraint"); 293ed35a92cSVlad Serebrennikov Str = End; 294ed35a92cSVlad Serebrennikov Mask = size; 295ed35a92cSVlad Serebrennikov return Context.IntTy; 296ed35a92cSVlad Serebrennikov } 297ed35a92cSVlad Serebrennikov case 'W': { 298ed35a92cSVlad Serebrennikov char *End; 299ed35a92cSVlad Serebrennikov unsigned size = strtoul(Str, &End, 10); 300ed35a92cSVlad Serebrennikov assert(End != Str && "Missing PowerPC MMA type size"); 301ed35a92cSVlad Serebrennikov Str = End; 302ed35a92cSVlad Serebrennikov QualType Type; 303ed35a92cSVlad Serebrennikov switch (size) { 304ed35a92cSVlad Serebrennikov #define PPC_VECTOR_TYPE(typeName, Id, size) \ 305ed35a92cSVlad Serebrennikov case size: \ 306ed35a92cSVlad Serebrennikov Type = Context.Id##Ty; \ 307ed35a92cSVlad Serebrennikov break; 308ed35a92cSVlad Serebrennikov #include "clang/Basic/PPCTypes.def" 309ed35a92cSVlad Serebrennikov default: 310ed35a92cSVlad Serebrennikov llvm_unreachable("Invalid PowerPC MMA vector type"); 311ed35a92cSVlad Serebrennikov } 312ed35a92cSVlad Serebrennikov bool CheckVectorArgs = false; 313ed35a92cSVlad Serebrennikov while (!CheckVectorArgs) { 314ed35a92cSVlad Serebrennikov switch (*Str++) { 315ed35a92cSVlad Serebrennikov case '*': 316ed35a92cSVlad Serebrennikov Type = Context.getPointerType(Type); 317ed35a92cSVlad Serebrennikov break; 318ed35a92cSVlad Serebrennikov case 'C': 319ed35a92cSVlad Serebrennikov Type = Type.withConst(); 320ed35a92cSVlad Serebrennikov break; 321ed35a92cSVlad Serebrennikov default: 322ed35a92cSVlad Serebrennikov CheckVectorArgs = true; 323ed35a92cSVlad Serebrennikov --Str; 324ed35a92cSVlad Serebrennikov break; 325ed35a92cSVlad Serebrennikov } 326ed35a92cSVlad Serebrennikov } 327ed35a92cSVlad Serebrennikov return Type; 328ed35a92cSVlad Serebrennikov } 329ed35a92cSVlad Serebrennikov default: 330ed35a92cSVlad Serebrennikov return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true); 331ed35a92cSVlad Serebrennikov } 332ed35a92cSVlad Serebrennikov } 333ed35a92cSVlad Serebrennikov 334ed35a92cSVlad Serebrennikov bool SemaPPC::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, 335ed35a92cSVlad Serebrennikov const char *TypeStr) { 336ed35a92cSVlad Serebrennikov 337ed35a92cSVlad Serebrennikov assert((TypeStr[0] != '\0') && 338ed35a92cSVlad Serebrennikov "Invalid types in PPC MMA builtin declaration"); 339ed35a92cSVlad Serebrennikov 340ed35a92cSVlad Serebrennikov ASTContext &Context = getASTContext(); 341ed35a92cSVlad Serebrennikov unsigned Mask = 0; 342ed35a92cSVlad Serebrennikov unsigned ArgNum = 0; 343ed35a92cSVlad Serebrennikov 344ed35a92cSVlad Serebrennikov // The first type in TypeStr is the type of the value returned by the 345ed35a92cSVlad Serebrennikov // builtin. So we first read that type and change the type of TheCall. 346ed35a92cSVlad Serebrennikov QualType type = DecodePPCMMATypeFromStr(Context, TypeStr, Mask); 347ed35a92cSVlad Serebrennikov TheCall->setType(type); 348ed35a92cSVlad Serebrennikov 349ed35a92cSVlad Serebrennikov while (*TypeStr != '\0') { 350ed35a92cSVlad Serebrennikov Mask = 0; 351ed35a92cSVlad Serebrennikov QualType ExpectedType = DecodePPCMMATypeFromStr(Context, TypeStr, Mask); 352ed35a92cSVlad Serebrennikov if (ArgNum >= TheCall->getNumArgs()) { 353ed35a92cSVlad Serebrennikov ArgNum++; 354ed35a92cSVlad Serebrennikov break; 355ed35a92cSVlad Serebrennikov } 356ed35a92cSVlad Serebrennikov 357ed35a92cSVlad Serebrennikov Expr *Arg = TheCall->getArg(ArgNum); 358ed35a92cSVlad Serebrennikov QualType PassedType = Arg->getType(); 359ed35a92cSVlad Serebrennikov QualType StrippedRVType = PassedType.getCanonicalType(); 360ed35a92cSVlad Serebrennikov 361ed35a92cSVlad Serebrennikov // Strip Restrict/Volatile qualifiers. 362ed35a92cSVlad Serebrennikov if (StrippedRVType.isRestrictQualified() || 363ed35a92cSVlad Serebrennikov StrippedRVType.isVolatileQualified()) 364ed35a92cSVlad Serebrennikov StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType(); 365ed35a92cSVlad Serebrennikov 366ed35a92cSVlad Serebrennikov // The only case where the argument type and expected type are allowed to 367ed35a92cSVlad Serebrennikov // mismatch is if the argument type is a non-void pointer (or array) and 368ed35a92cSVlad Serebrennikov // expected type is a void pointer. 369ed35a92cSVlad Serebrennikov if (StrippedRVType != ExpectedType) 370ed35a92cSVlad Serebrennikov if (!(ExpectedType->isVoidPointerType() && 371ed35a92cSVlad Serebrennikov (StrippedRVType->isPointerType() || StrippedRVType->isArrayType()))) 372ed35a92cSVlad Serebrennikov return Diag(Arg->getBeginLoc(), 373ed35a92cSVlad Serebrennikov diag::err_typecheck_convert_incompatible) 374ed35a92cSVlad Serebrennikov << PassedType << ExpectedType << 1 << 0 << 0; 375ed35a92cSVlad Serebrennikov 376ed35a92cSVlad Serebrennikov // If the value of the Mask is not 0, we have a constraint in the size of 377ed35a92cSVlad Serebrennikov // the integer argument so here we ensure the argument is a constant that 378ed35a92cSVlad Serebrennikov // is in the valid range. 379ed35a92cSVlad Serebrennikov if (Mask != 0 && 380ed35a92cSVlad Serebrennikov SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, Mask, true)) 381ed35a92cSVlad Serebrennikov return true; 382ed35a92cSVlad Serebrennikov 383ed35a92cSVlad Serebrennikov ArgNum++; 384ed35a92cSVlad Serebrennikov } 385ed35a92cSVlad Serebrennikov 386ed35a92cSVlad Serebrennikov // In case we exited early from the previous loop, there are other types to 387ed35a92cSVlad Serebrennikov // read from TypeStr. So we need to read them all to ensure we have the right 388ed35a92cSVlad Serebrennikov // number of arguments in TheCall and if it is not the case, to display a 389ed35a92cSVlad Serebrennikov // better error message. 390ed35a92cSVlad Serebrennikov while (*TypeStr != '\0') { 391ed35a92cSVlad Serebrennikov (void)DecodePPCMMATypeFromStr(Context, TypeStr, Mask); 392ed35a92cSVlad Serebrennikov ArgNum++; 393ed35a92cSVlad Serebrennikov } 394ed35a92cSVlad Serebrennikov if (SemaRef.checkArgCount(TheCall, ArgNum)) 395ed35a92cSVlad Serebrennikov return true; 396ed35a92cSVlad Serebrennikov 397ed35a92cSVlad Serebrennikov return false; 398ed35a92cSVlad Serebrennikov } 399ed35a92cSVlad Serebrennikov 400ed35a92cSVlad Serebrennikov bool SemaPPC::BuiltinVSX(CallExpr *TheCall) { 401ed35a92cSVlad Serebrennikov unsigned ExpectedNumArgs = 3; 402ed35a92cSVlad Serebrennikov if (SemaRef.checkArgCount(TheCall, ExpectedNumArgs)) 403ed35a92cSVlad Serebrennikov return true; 404ed35a92cSVlad Serebrennikov 405ed35a92cSVlad Serebrennikov // Check the third argument is a compile time constant 406ed35a92cSVlad Serebrennikov if (!TheCall->getArg(2)->isIntegerConstantExpr(getASTContext())) 407ed35a92cSVlad Serebrennikov return Diag(TheCall->getBeginLoc(), 408ed35a92cSVlad Serebrennikov diag::err_vsx_builtin_nonconstant_argument) 409ed35a92cSVlad Serebrennikov << 3 /* argument index */ << TheCall->getDirectCallee() 410ed35a92cSVlad Serebrennikov << SourceRange(TheCall->getArg(2)->getBeginLoc(), 411ed35a92cSVlad Serebrennikov TheCall->getArg(2)->getEndLoc()); 412ed35a92cSVlad Serebrennikov 413ed35a92cSVlad Serebrennikov QualType Arg1Ty = TheCall->getArg(0)->getType(); 414ed35a92cSVlad Serebrennikov QualType Arg2Ty = TheCall->getArg(1)->getType(); 415ed35a92cSVlad Serebrennikov 416ed35a92cSVlad Serebrennikov // Check the type of argument 1 and argument 2 are vectors. 417ed35a92cSVlad Serebrennikov SourceLocation BuiltinLoc = TheCall->getBeginLoc(); 418ed35a92cSVlad Serebrennikov if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) || 419ed35a92cSVlad Serebrennikov (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) { 420ed35a92cSVlad Serebrennikov return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector) 421ed35a92cSVlad Serebrennikov << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false 422ed35a92cSVlad Serebrennikov << SourceRange(TheCall->getArg(0)->getBeginLoc(), 423ed35a92cSVlad Serebrennikov TheCall->getArg(1)->getEndLoc()); 424ed35a92cSVlad Serebrennikov } 425ed35a92cSVlad Serebrennikov 426ed35a92cSVlad Serebrennikov // Check the first two arguments are the same type. 427ed35a92cSVlad Serebrennikov if (!getASTContext().hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) { 428ed35a92cSVlad Serebrennikov return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector) 429ed35a92cSVlad Serebrennikov << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false 430ed35a92cSVlad Serebrennikov << SourceRange(TheCall->getArg(0)->getBeginLoc(), 431ed35a92cSVlad Serebrennikov TheCall->getArg(1)->getEndLoc()); 432ed35a92cSVlad Serebrennikov } 433ed35a92cSVlad Serebrennikov 434ed35a92cSVlad Serebrennikov // When default clang type checking is turned off and the customized type 435ed35a92cSVlad Serebrennikov // checking is used, the returning type of the function must be explicitly 436ed35a92cSVlad Serebrennikov // set. Otherwise it is _Bool by default. 437ed35a92cSVlad Serebrennikov TheCall->setType(Arg1Ty); 438ed35a92cSVlad Serebrennikov 439ed35a92cSVlad Serebrennikov return false; 440ed35a92cSVlad Serebrennikov } 441ed35a92cSVlad Serebrennikov 442ed35a92cSVlad Serebrennikov } // namespace clang 443