diff options
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
| -rw-r--r-- | lib/Sema/SemaChecking.cpp | 198 | 
1 files changed, 194 insertions, 4 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index b8e7ede2716c9..7f7dbe8873d4e 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1454,8 +1454,17 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,    return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);  } +// CheckMipsBuiltinFunctionCall - Checks the constant value passed to the +// intrinsic is correct. The switch statement is ordered by DSP, MSA. The +// ordering for DSP is unspecified. MSA is ordered by the data format used +// by the underlying instruction i.e., df/m, df/n and then by size. +// +// FIXME: The size tests here should instead be tablegen'd along with the +//        definitions from include/clang/Basic/BuiltinsMips.def. +// FIXME: GCC is strict on signedness for some of these intrinsics, we should +//        be too.  bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { -  unsigned i = 0, l = 0, u = 0; +  unsigned i = 0, l = 0, u = 0, m = 0;    switch (BuiltinID) {    default: return false;    case Mips::BI__builtin_mips_wrdsp: i = 1; l = 0; u = 63; break; @@ -1465,9 +1474,168 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {    case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break;    case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break;    case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; -  } - -  return SemaBuiltinConstantArgRange(TheCall, i, l, u); +  // MSA instrinsics. Instructions (which the intrinsics maps to) which use the +  // df/m field. +  // These intrinsics take an unsigned 3 bit immediate. +  case Mips::BI__builtin_msa_bclri_b: +  case Mips::BI__builtin_msa_bnegi_b: +  case Mips::BI__builtin_msa_bseti_b: +  case Mips::BI__builtin_msa_sat_s_b: +  case Mips::BI__builtin_msa_sat_u_b: +  case Mips::BI__builtin_msa_slli_b: +  case Mips::BI__builtin_msa_srai_b: +  case Mips::BI__builtin_msa_srari_b: +  case Mips::BI__builtin_msa_srli_b: +  case Mips::BI__builtin_msa_srlri_b: i = 1; l = 0; u = 7; break; +  case Mips::BI__builtin_msa_binsli_b: +  case Mips::BI__builtin_msa_binsri_b: i = 2; l = 0; u = 7; break; +  // These intrinsics take an unsigned 4 bit immediate. +  case Mips::BI__builtin_msa_bclri_h: +  case Mips::BI__builtin_msa_bnegi_h: +  case Mips::BI__builtin_msa_bseti_h: +  case Mips::BI__builtin_msa_sat_s_h: +  case Mips::BI__builtin_msa_sat_u_h: +  case Mips::BI__builtin_msa_slli_h: +  case Mips::BI__builtin_msa_srai_h: +  case Mips::BI__builtin_msa_srari_h: +  case Mips::BI__builtin_msa_srli_h: +  case Mips::BI__builtin_msa_srlri_h: i = 1; l = 0; u = 15; break; +  case Mips::BI__builtin_msa_binsli_h: +  case Mips::BI__builtin_msa_binsri_h: i = 2; l = 0; u = 15; break; +  // These intrinsics take an unsigned 5 bit immedate. +  // The first block of intrinsics actually have an unsigned 5 bit field, +  // not a df/n field. +  case Mips::BI__builtin_msa_clei_u_b: +  case Mips::BI__builtin_msa_clei_u_h: +  case Mips::BI__builtin_msa_clei_u_w: +  case Mips::BI__builtin_msa_clei_u_d: +  case Mips::BI__builtin_msa_clti_u_b: +  case Mips::BI__builtin_msa_clti_u_h: +  case Mips::BI__builtin_msa_clti_u_w: +  case Mips::BI__builtin_msa_clti_u_d: +  case Mips::BI__builtin_msa_maxi_u_b: +  case Mips::BI__builtin_msa_maxi_u_h: +  case Mips::BI__builtin_msa_maxi_u_w: +  case Mips::BI__builtin_msa_maxi_u_d: +  case Mips::BI__builtin_msa_mini_u_b: +  case Mips::BI__builtin_msa_mini_u_h: +  case Mips::BI__builtin_msa_mini_u_w: +  case Mips::BI__builtin_msa_mini_u_d: +  case Mips::BI__builtin_msa_addvi_b: +  case Mips::BI__builtin_msa_addvi_h: +  case Mips::BI__builtin_msa_addvi_w: +  case Mips::BI__builtin_msa_addvi_d: +  case Mips::BI__builtin_msa_bclri_w: +  case Mips::BI__builtin_msa_bnegi_w: +  case Mips::BI__builtin_msa_bseti_w: +  case Mips::BI__builtin_msa_sat_s_w: +  case Mips::BI__builtin_msa_sat_u_w: +  case Mips::BI__builtin_msa_slli_w: +  case Mips::BI__builtin_msa_srai_w: +  case Mips::BI__builtin_msa_srari_w: +  case Mips::BI__builtin_msa_srli_w: +  case Mips::BI__builtin_msa_srlri_w: +  case Mips::BI__builtin_msa_subvi_b: +  case Mips::BI__builtin_msa_subvi_h: +  case Mips::BI__builtin_msa_subvi_w: +  case Mips::BI__builtin_msa_subvi_d: i = 1; l = 0; u = 31; break; +  case Mips::BI__builtin_msa_binsli_w: +  case Mips::BI__builtin_msa_binsri_w: i = 2; l = 0; u = 31; break; +  // These intrinsics take an unsigned 6 bit immediate. +  case Mips::BI__builtin_msa_bclri_d: +  case Mips::BI__builtin_msa_bnegi_d: +  case Mips::BI__builtin_msa_bseti_d: +  case Mips::BI__builtin_msa_sat_s_d: +  case Mips::BI__builtin_msa_sat_u_d: +  case Mips::BI__builtin_msa_slli_d: +  case Mips::BI__builtin_msa_srai_d: +  case Mips::BI__builtin_msa_srari_d: +  case Mips::BI__builtin_msa_srli_d: +  case Mips::BI__builtin_msa_srlri_d: i = 1; l = 0; u = 63; break; +  case Mips::BI__builtin_msa_binsli_d: +  case Mips::BI__builtin_msa_binsri_d: i = 2; l = 0; u = 63; break; +  // These intrinsics take a signed 5 bit immediate. +  case Mips::BI__builtin_msa_ceqi_b: +  case Mips::BI__builtin_msa_ceqi_h: +  case Mips::BI__builtin_msa_ceqi_w: +  case Mips::BI__builtin_msa_ceqi_d: +  case Mips::BI__builtin_msa_clti_s_b: +  case Mips::BI__builtin_msa_clti_s_h: +  case Mips::BI__builtin_msa_clti_s_w: +  case Mips::BI__builtin_msa_clti_s_d: +  case Mips::BI__builtin_msa_clei_s_b: +  case Mips::BI__builtin_msa_clei_s_h: +  case Mips::BI__builtin_msa_clei_s_w: +  case Mips::BI__builtin_msa_clei_s_d: +  case Mips::BI__builtin_msa_maxi_s_b: +  case Mips::BI__builtin_msa_maxi_s_h: +  case Mips::BI__builtin_msa_maxi_s_w: +  case Mips::BI__builtin_msa_maxi_s_d: +  case Mips::BI__builtin_msa_mini_s_b: +  case Mips::BI__builtin_msa_mini_s_h: +  case Mips::BI__builtin_msa_mini_s_w: +  case Mips::BI__builtin_msa_mini_s_d: i = 1; l = -16; u = 15; break; +  // These intrinsics take an unsigned 8 bit immediate. +  case Mips::BI__builtin_msa_andi_b: +  case Mips::BI__builtin_msa_nori_b: +  case Mips::BI__builtin_msa_ori_b: +  case Mips::BI__builtin_msa_shf_b: +  case Mips::BI__builtin_msa_shf_h: +  case Mips::BI__builtin_msa_shf_w: +  case Mips::BI__builtin_msa_xori_b: i = 1; l = 0; u = 255; break; +  case Mips::BI__builtin_msa_bseli_b: +  case Mips::BI__builtin_msa_bmnzi_b: +  case Mips::BI__builtin_msa_bmzi_b: i = 2; l = 0; u = 255; break; +  // df/n format +  // These intrinsics take an unsigned 4 bit immediate. +  case Mips::BI__builtin_msa_copy_s_b: +  case Mips::BI__builtin_msa_copy_u_b: +  case Mips::BI__builtin_msa_insve_b: +  case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; +  case Mips::BI__builtin_msa_sld_b: +  case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; +  // These intrinsics take an unsigned 3 bit immediate. +  case Mips::BI__builtin_msa_copy_s_h: +  case Mips::BI__builtin_msa_copy_u_h: +  case Mips::BI__builtin_msa_insve_h: +  case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; +  case Mips::BI__builtin_msa_sld_h: +  case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; +  // These intrinsics take an unsigned 2 bit immediate. +  case Mips::BI__builtin_msa_copy_s_w: +  case Mips::BI__builtin_msa_copy_u_w: +  case Mips::BI__builtin_msa_insve_w: +  case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; +  case Mips::BI__builtin_msa_sld_w: +  case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; +  // These intrinsics take an unsigned 1 bit immediate. +  case Mips::BI__builtin_msa_copy_s_d: +  case Mips::BI__builtin_msa_copy_u_d: +  case Mips::BI__builtin_msa_insve_d: +  case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; +  case Mips::BI__builtin_msa_sld_d: +  case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; +  // Memory offsets and immediate loads. +  // These intrinsics take a signed 10 bit immediate. +  case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 127; break; +  case Mips::BI__builtin_msa_ldi_h: +  case Mips::BI__builtin_msa_ldi_w: +  case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; +  case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 16; break; +  case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 16; break; +  case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 16; break; +  case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 16; break; +  case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 16; break; +  case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 16; break; +  case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 16; break; +  case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 16; break; +  } + +  if (!m) +    return SemaBuiltinConstantArgRange(TheCall, i, l, u); + +  return SemaBuiltinConstantArgRange(TheCall, i, l, u) || +         SemaBuiltinConstantArgMultiple(TheCall, i, m);  }  bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { @@ -3605,6 +3773,28 @@ bool Sema::SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,    return false;  } +/// SemaBuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr +/// TheCall is a constant expression is a multiple of Num.. +bool Sema::SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, +                                          unsigned Num) { +  llvm::APSInt Result; + +  // We can't check the value of a dependent argument. +  Expr *Arg = TheCall->getArg(ArgNum); +  if (Arg->isTypeDependent() || Arg->isValueDependent()) +    return false; + +  // Check constant-ness first. +  if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) +    return true; + +  if (Result.getSExtValue() % Num != 0) +    return Diag(TheCall->getLocStart(), diag::err_argument_not_multiple) +      << Num << Arg->getSourceRange(); + +  return false; +} +  /// SemaBuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr  /// TheCall is an ARM/AArch64 special register string literal.  bool Sema::SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,  | 
