//===------ SemaPPC.cpp ------ PowerPC target-specific routines -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file implements semantic analysis functions specific to PowerPC.
//
//===----------------------------------------------------------------------===//

#include "clang/Sema/SemaPPC.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/APSInt.h"

namespace clang {

SemaPPC::SemaPPC(Sema &S) : SemaBase(S) {}

void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) {
  const auto *ICE = dyn_cast<ImplicitCastExpr>(Arg->IgnoreParens());
  if (!ICE)
    return;

  const auto *DR = dyn_cast<DeclRefExpr>(ICE->getSubExpr());
  if (!DR)
    return;

  const auto *PD = dyn_cast<ParmVarDecl>(DR->getDecl());
  if (!PD || !PD->getType()->isRecordType())
    return;

  QualType ArgType = Arg->getType();
  for (const FieldDecl *FD : ArgType->castAsRecordDecl()->fields()) {
    if (const auto *AA = FD->getAttr<AlignedAttr>()) {
      CharUnits Alignment = getASTContext().toCharUnitsFromBits(
          AA->getAlignment(getASTContext()));
      if (Alignment.getQuantity() == 16) {
        Diag(FD->getLocation(), diag::warn_not_xl_compatible) << FD;
        Diag(Loc, diag::note_misaligned_member_used_here) << PD;
      }
    }
  }
}

static bool isPPC_64Builtin(unsigned BuiltinID) {
  // These builtins only work on PPC 64bit targets.
  switch (BuiltinID) {
  case PPC::BI__builtin_divde:
  case PPC::BI__builtin_divdeu:
  case PPC::BI__builtin_bpermd:
  case PPC::BI__builtin_pdepd:
  case PPC::BI__builtin_pextd:
  case PPC::BI__builtin_ppc_cdtbcd:
  case PPC::BI__builtin_ppc_cbcdtd:
  case PPC::BI__builtin_ppc_addg6s:
  case PPC::BI__builtin_ppc_ldarx:
  case PPC::BI__builtin_ppc_stdcx:
  case PPC::BI__builtin_ppc_tdw:
  case PPC::BI__builtin_ppc_trapd:
  case PPC::BI__builtin_ppc_cmpeqb:
  case PPC::BI__builtin_ppc_setb:
  case PPC::BI__builtin_ppc_mulhd:
  case PPC::BI__builtin_ppc_mulhdu:
  case PPC::BI__builtin_ppc_maddhd:
  case PPC::BI__builtin_ppc_maddhdu:
  case PPC::BI__builtin_ppc_maddld:
  case PPC::BI__builtin_ppc_load8r:
  case PPC::BI__builtin_ppc_store8r:
  case PPC::BI__builtin_ppc_insert_exp:
  case PPC::BI__builtin_ppc_extract_sig:
  case PPC::BI__builtin_ppc_addex:
  case PPC::BI__builtin_darn:
  case PPC::BI__builtin_darn_raw:
  case PPC::BI__builtin_ppc_compare_and_swaplp:
  case PPC::BI__builtin_ppc_fetch_and_addlp:
  case PPC::BI__builtin_ppc_fetch_and_andlp:
  case PPC::BI__builtin_ppc_fetch_and_orlp:
  case PPC::BI__builtin_ppc_fetch_and_swaplp:
    return true;
  }
  return false;
}

bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
                                          unsigned BuiltinID,
                                          CallExpr *TheCall) {
  ASTContext &Context = getASTContext();
  bool IsTarget64Bit = TI.getTypeWidth(TI.getIntPtrType()) == 64;

  if (isPPC_64Builtin(BuiltinID) && !IsTarget64Bit)
    return Diag(TheCall->getBeginLoc(), diag::err_64_bit_builtin_32_bit_tgt)
           << TheCall->getSourceRange();

  switch (BuiltinID) {
  default:
    return false;
  case PPC::BI__builtin_ppc_bcdsetsign:
  case PPC::BI__builtin_ppc_national2packed:
  case PPC::BI__builtin_ppc_packed2zoned:
  case PPC::BI__builtin_ppc_zoned2packed:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
  case PPC::BI__builtin_altivec_crypto_vshasigmaw:
  case PPC::BI__builtin_altivec_crypto_vshasigmad:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1) ||
           SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 15);
  case PPC::BI__builtin_altivec_dss:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3);
  case PPC::BI__builtin_tbegin:
  case PPC::BI__builtin_tend:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
  case PPC::BI__builtin_tsr:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7);
  case PPC::BI__builtin_tabortwc:
  case PPC::BI__builtin_tabortdc:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
  case PPC::BI__builtin_tabortwci:
  case PPC::BI__builtin_tabortdci:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31) ||
           SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31);
  // According to GCC 'Basic PowerPC Built-in Functions Available on ISA 2.05',
  // __builtin_(un)pack_longdouble are available only if long double uses IBM
  // extended double representation.
  case PPC::BI__builtin_unpack_longdouble:
    if (SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1))
      return true;
    [[fallthrough]];
  case PPC::BI__builtin_pack_longdouble:
    if (&TI.getLongDoubleFormat() != &llvm::APFloat::PPCDoubleDouble())
      return Diag(TheCall->getBeginLoc(), diag::err_ppc_builtin_requires_abi)
             << "ibmlongdouble";
    return false;
  case PPC::BI__builtin_altivec_dst:
  case PPC::BI__builtin_altivec_dstt:
  case PPC::BI__builtin_altivec_dstst:
  case PPC::BI__builtin_altivec_dststt:
    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3);
  case PPC::BI__builtin_vsx_xxpermdi:
  case PPC::BI__builtin_vsx_xxsldwi:
    return BuiltinVSX(TheCall);
  case PPC::BI__builtin_unpack_vector_int128:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
  case PPC::BI__builtin_altivec_vgnb:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 2, 7);
  case PPC::BI__builtin_vsx_xxeval:
    return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 255);
  case PPC::BI__builtin_altivec_vsldbi:
    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
  case PPC::BI__builtin_altivec_vsrdbi:
    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 7);
  case PPC::BI__builtin_vsx_xxpermx:
    return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 7);
  case PPC::BI__builtin_ppc_tw:
  case PPC::BI__builtin_ppc_tdw:
    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 31);
  case PPC::BI__builtin_ppc_cmprb:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
  // For __rlwnm, __rlwimi and __rldimi, the last parameter mask must
  // be a constant that represents a contiguous bit field.
  case PPC::BI__builtin_ppc_rlwnm:
    return SemaRef.ValueIsRunOfOnes(TheCall, 2);
  case PPC::BI__builtin_ppc_rlwimi:
    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) ||
           SemaRef.ValueIsRunOfOnes(TheCall, 3);
  case PPC::BI__builtin_ppc_rldimi:
    return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 63) ||
           SemaRef.ValueIsRunOfOnes(TheCall, 3);
  case PPC::BI__builtin_ppc_addex: {
    if (SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3))
      return true;
    // Output warning for reserved values 1 to 3.
    int ArgValue =
        TheCall->getArg(2)->getIntegerConstantExpr(Context)->getSExtValue();
    if (ArgValue != 0)
      Diag(TheCall->getBeginLoc(), diag::warn_argument_undefined_behaviour)
          << ArgValue;
    return false;
  }
  case PPC::BI__builtin_ppc_mtfsb0:
  case PPC::BI__builtin_ppc_mtfsb1:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 31);
  case PPC::BI__builtin_ppc_mtfsf:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 255);
  case PPC::BI__builtin_ppc_mtfsfi:
    return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 7) ||
           SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 15);
  case PPC::BI__builtin_ppc_alignx:
    return SemaRef.BuiltinConstantArgPower2(TheCall, 0);
  case PPC::BI__builtin_ppc_rdlam:
    return SemaRef.ValueIsRunOfOnes(TheCall, 2);
  case PPC::BI__builtin_vsx_ldrmb:
  case PPC::BI__builtin_vsx_strmb:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 1, 16);
  case PPC::BI__builtin_altivec_vcntmbb:
  case PPC::BI__builtin_altivec_vcntmbh:
  case PPC::BI__builtin_altivec_vcntmbw:
  case PPC::BI__builtin_altivec_vcntmbd:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 1);
  case PPC::BI__builtin_vsx_xxgenpcvbm:
  case PPC::BI__builtin_vsx_xxgenpcvhm:
  case PPC::BI__builtin_vsx_xxgenpcvwm:
  case PPC::BI__builtin_vsx_xxgenpcvdm:
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3);
  case PPC::BI__builtin_ppc_test_data_class: {
    // Check if the first argument of the __builtin_ppc_test_data_class call is
    // valid. The argument must be 'float' or 'double' or '__float128'.
    QualType ArgType = TheCall->getArg(0)->getType();
    if (ArgType != QualType(Context.FloatTy) &&
        ArgType != QualType(Context.DoubleTy) &&
        ArgType != QualType(Context.Float128Ty))
      return Diag(TheCall->getBeginLoc(),
                  diag::err_ppc_invalid_test_data_class_type);
    return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 127);
  }
  case PPC::BI__builtin_ppc_maxfe:
  case PPC::BI__builtin_ppc_minfe:
  case PPC::BI__builtin_ppc_maxfl:
  case PPC::BI__builtin_ppc_minfl:
  case PPC::BI__builtin_ppc_maxfs:
  case PPC::BI__builtin_ppc_minfs: {
    if (Context.getTargetInfo().getTriple().isOSAIX() &&
        (BuiltinID == PPC::BI__builtin_ppc_maxfe ||
         BuiltinID == PPC::BI__builtin_ppc_minfe))
      return Diag(TheCall->getBeginLoc(), diag::err_target_unsupported_type)
             << "builtin" << true << 128 << QualType(Context.LongDoubleTy)
             << false << Context.getTargetInfo().getTriple().str();
    // Argument type should be exact.
    QualType ArgType = QualType(Context.LongDoubleTy);
    if (BuiltinID == PPC::BI__builtin_ppc_maxfl ||
        BuiltinID == PPC::BI__builtin_ppc_minfl)
      ArgType = QualType(Context.DoubleTy);
    else if (BuiltinID == PPC::BI__builtin_ppc_maxfs ||
             BuiltinID == PPC::BI__builtin_ppc_minfs)
      ArgType = QualType(Context.FloatTy);
    for (unsigned I = 0, E = TheCall->getNumArgs(); I < E; ++I)
      if (TheCall->getArg(I)->getType() != ArgType)
        return Diag(TheCall->getBeginLoc(),
                    diag::err_typecheck_convert_incompatible)
               << TheCall->getArg(I)->getType() << ArgType << 1 << 0 << 0;
    return false;
  }
#define CUSTOM_BUILTIN(Name, Intr, Types, Acc, Feature)                        \
  case PPC::BI__builtin_##Name:                                                \
    return BuiltinPPCMMACall(TheCall, BuiltinID, Types);
#include "clang/Basic/BuiltinsPPC.def"
  }
  llvm_unreachable("must return from switch");
}

// Check if the given type is a non-pointer PPC MMA type. This function is used
// in Sema to prevent invalid uses of restricted PPC MMA types.
bool SemaPPC::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) {
  ASTContext &Context = getASTContext();
  if (Type->isPointerType() || Type->isArrayType())
    return false;

  QualType CoreType = Type.getCanonicalType().getUnqualifiedType();
#define PPC_VECTOR_TYPE(Name, Id, Size) || CoreType == Context.Id##Ty
  if (false
#include "clang/Basic/PPCTypes.def"
  ) {
    Diag(TypeLoc, diag::err_ppc_invalid_use_mma_type);
    return true;
  }
  return false;
}

/// DecodePPCMMATypeFromStr - This decodes one PPC MMA type descriptor from Str,
/// advancing the pointer over the consumed characters. The decoded type is
/// returned. If the decoded type represents a constant integer with a
/// constraint on its value then Mask is set to that value. The type descriptors
/// used in Str are specific to PPC MMA builtins and are documented in the file
/// defining the PPC builtins.
static QualType DecodePPCMMATypeFromStr(ASTContext &Context, const char *&Str,
                                        unsigned &Mask) {
  bool RequireICE = false;
  ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None;
  switch (*Str++) {
  case 'V':
    return Context.getVectorType(Context.UnsignedCharTy, 16,
                                 VectorKind::AltiVecVector);
  case 'i': {
    char *End;
    unsigned size = strtoul(Str, &End, 10);
    assert(End != Str && "Missing constant parameter constraint");
    Str = End;
    Mask = size;
    return Context.IntTy;
  }
  case 'W': {
    char *End;
    unsigned size = strtoul(Str, &End, 10);
    assert(End != Str && "Missing PowerPC MMA type size");
    Str = End;
    QualType Type;
    switch (size) {
#define PPC_VECTOR_TYPE(typeName, Id, size)                                    \
  case size:                                                                   \
    Type = Context.Id##Ty;                                                     \
    break;
#include "clang/Basic/PPCTypes.def"
    default:
      llvm_unreachable("Invalid PowerPC MMA vector type");
    }
    bool CheckVectorArgs = false;
    while (!CheckVectorArgs) {
      switch (*Str++) {
      case '*':
        Type = Context.getPointerType(Type);
        break;
      case 'C':
        Type = Type.withConst();
        break;
      default:
        CheckVectorArgs = true;
        --Str;
        break;
      }
    }
    return Type;
  }
  default:
    return Context.DecodeTypeStr(--Str, Context, Error, RequireICE, true);
  }
}

bool SemaPPC::BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID,
                                const char *TypeStr) {

  assert((TypeStr[0] != '\0') &&
         "Invalid types in PPC MMA builtin declaration");

  ASTContext &Context = getASTContext();
  unsigned Mask = 0;
  unsigned ArgNum = 0;

  // The first type in TypeStr is the type of the value returned by the
  // builtin. So we first read that type and change the type of TheCall.
  QualType type = DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
  TheCall->setType(type);

  while (*TypeStr != '\0') {
    Mask = 0;
    QualType ExpectedType = DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
    if (ArgNum >= TheCall->getNumArgs()) {
      ArgNum++;
      break;
    }

    Expr *Arg = TheCall->getArg(ArgNum);
    QualType PassedType = Arg->getType();
    QualType StrippedRVType = PassedType.getCanonicalType();

    // Strip Restrict/Volatile qualifiers.
    if (StrippedRVType.isRestrictQualified() ||
        StrippedRVType.isVolatileQualified())
      StrippedRVType = StrippedRVType.getCanonicalType().getUnqualifiedType();

    // The only case where the argument type and expected type are allowed to
    // mismatch is if the argument type is a non-void pointer (or array) and
    // expected type is a void pointer.
    if (StrippedRVType != ExpectedType)
      if (!(ExpectedType->isVoidPointerType() &&
            (StrippedRVType->isPointerType() || StrippedRVType->isArrayType())))
        return Diag(Arg->getBeginLoc(),
                    diag::err_typecheck_convert_incompatible)
               << PassedType << ExpectedType << 1 << 0 << 0;

    // If the value of the Mask is not 0, we have a constraint in the size of
    // the integer argument so here we ensure the argument is a constant that
    // is in the valid range.
    if (Mask != 0 &&
        SemaRef.BuiltinConstantArgRange(TheCall, ArgNum, 0, Mask, true))
      return true;

    ArgNum++;
  }

  // In case we exited early from the previous loop, there are other types to
  // read from TypeStr. So we need to read them all to ensure we have the right
  // number of arguments in TheCall and if it is not the case, to display a
  // better error message.
  while (*TypeStr != '\0') {
    (void)DecodePPCMMATypeFromStr(Context, TypeStr, Mask);
    ArgNum++;
  }
  if (SemaRef.checkArgCount(TheCall, ArgNum))
    return true;

  return false;
}

bool SemaPPC::BuiltinVSX(CallExpr *TheCall) {
  unsigned ExpectedNumArgs = 3;
  if (SemaRef.checkArgCount(TheCall, ExpectedNumArgs))
    return true;

  // Check the third argument is a compile time constant
  if (!TheCall->getArg(2)->isIntegerConstantExpr(getASTContext()))
    return Diag(TheCall->getBeginLoc(),
                diag::err_vsx_builtin_nonconstant_argument)
           << 3 /* argument index */ << TheCall->getDirectCallee()
           << SourceRange(TheCall->getArg(2)->getBeginLoc(),
                          TheCall->getArg(2)->getEndLoc());

  QualType Arg1Ty = TheCall->getArg(0)->getType();
  QualType Arg2Ty = TheCall->getArg(1)->getType();

  // Check the type of argument 1 and argument 2 are vectors.
  SourceLocation BuiltinLoc = TheCall->getBeginLoc();
  if ((!Arg1Ty->isVectorType() && !Arg1Ty->isDependentType()) ||
      (!Arg2Ty->isVectorType() && !Arg2Ty->isDependentType())) {
    return Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
           << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false
           << SourceRange(TheCall->getArg(0)->getBeginLoc(),
                          TheCall->getArg(1)->getEndLoc());
  }

  // Check the first two arguments are the same type.
  if (!getASTContext().hasSameUnqualifiedType(Arg1Ty, Arg2Ty)) {
    return Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
           << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ false
           << SourceRange(TheCall->getArg(0)->getBeginLoc(),
                          TheCall->getArg(1)->getEndLoc());
  }

  // When default clang type checking is turned off and the customized type
  // checking is used, the returning type of the function must be explicitly
  // set. Otherwise it is _Bool by default.
  TheCall->setType(Arg1Ty);

  return false;
}

} // namespace clang
